2013-10-11 2 views
2

В последнее время я обнаружил, что пишу много классов, подобных:доступа «это» внутри статических CodeBlocks

public class MyTypeCodes 
{ 
    public static MyTypeCode E = new MyTypeCode{ Desc= "EEE", Value = "E" }; 
    public static MyTypeCode I = new MyTypeCode { Desc= "III", Value = "I" }; 

    private static readonly Lazy<IEnumerable<MyTypeCode>> AllMyTypeCodes = 
     new Lazy<IEnumerable<MyTypeCode>>(() => 
     { 
      var typeCodes = typeof(MyTypeCodes) 
       .GetFields(BindingFlags.Static | BindingFlags.Public) 
       .Where(x => x.FieldType == typeof (MyTypeCode)) 
       .Select(x => (MyTypeCode) x.GetValue(null)) 
       .ToList(); 

       return typeCodes; 
     }); 

    public static IEnumerable<MyTypeCode> All 
    { 
     get { return AllMyTypeCodes.Value; } 
    } 
} 

Если вы заметили внутри new Lazy<IEnumerable<MyTypeCode>>(() =>, что я специально нужно сделать typeof(MyTypeCodes), даже если я внутри класса MyTypeCodes. Есть ли способ, которым я могу написать это без необходимости звонить typeof() для класса, в котором я непосредственно внутри? Если бы это был обычный метод, я бы this.GetType(), который, очевидно, не работает (по какой-то причине) со статикой.

+4

FYI - Вы должны использовать 'ToList()' на 'IEnumerable' последовательности здесь ... В противном случае, каждый вызов будет снова проходить через отражение. –

ответ

2

Есть ли способ написать это без необходимости вызова typeof() для класса i именно внутри?

Нет, это, скорее всего, лучший вариант. Если вы знаете, что никогда не будете добавлять какие-либо другие поля, любых других типов, вы можете просто пропустить предложение Where.

Кроме того, вы должны использовать ToList() для предотвращения IEnumerable<T> генерируемых от необходимости повторно каждый раз, когда он перечисленный:

private static readonly Lazy<IEnumerable<MyTypeCode>> AllMyTypeCodes = 
    new Lazy<IEnumerable<MyTypeCode>>(() => 
    { 
     return typeof(MyTypeCodes) 
      .GetFields(BindingFlags.Static | BindingFlags.Public) 
      // If you're not using any other fields, just skip this 
      // .Where(x => x.FieldType == typeof (MyTypeCode)) 
      .Select(x => (MyTypeCode) x.GetValue(null)) 
      .ToList();     
    }); 
+0

Я нахожу это действительно глупым, что это должно быть так –

+0

@ChrisMarisic 'this' относится к экземпляру на C#. Для этого должно быть какое-то другое ключевое слово, но там просто нет языка ... –

+0

Я так понимаю, я просто не согласен с этим. Это внутри статической области следует ссылаться на этот экземпляр, который может быть статичным. –

0

сделать приватный конструктор, который дает вам (частную) ссылку.

private MyTypeCodes() { } 
private static MyTypeCodes _instance = new MyTypeCodes(); 

public static DoSomethingWithType() 
{ 
    return _instance.GetType().foo(); 
} 

Или вы могли бы иметь GetType конструктор вызова() и просто использовать, что вместо вызова _instance.GetType() каждый раз, когда вам это нужно.

0

Если вы предпочитаете семантику, вы могли бы сделать:

private static readonly Type _thisType = typeof(MyTypeCodes); 

// use like 
var typeCodes = _thisType.GetFields(... 
Смежные вопросы