2013-03-25 70 views
1

我對C#中的反射很新穎。我想創建一個特定的屬性,我可以使用我的字段,所以我可以通過它們全部並檢查它們是否已正確初始化,而不是每次爲每個字段寫入這些檢查。我認爲這將是這個樣子:通過具有特定屬性的字段進行迭代

public abstract class BaseClass { 

    public void Awake() { 

     foreach(var s in GetAllFieldsWithAttribute("ShouldBeInitialized")) { 

      if (!s) { 

       Debug.LogWarning("Variable " + s.FieldName + " should be initialized!"); 
       enabled = false; 

      } 

     } 

    } 

} 

public class ChildClass : BasicClass { 

    [ShouldBeInitialized] 
    public SomeClass someObject; 

    [ShouldBeInitialized] 
    public int? someInteger; 

} 

(您可能注意到,我打算用它Unity3d,但沒有什麼具體到Unity在這個問題上 - 或者至少,它似乎很給我)。這可能嗎?

+0

是否System.Attribute.IsDefined (FieldInfo,Type)是否統一? – 2013-03-25 17:28:32

+0

是的,它的確如此。謝謝 - 我認爲我可以通過谷歌我的出路,但仍然不完全確定如何使用它... – 2013-03-25 17:32:09

回答

2

你可以簡單地用表達式:通過使上Type擴展方法

foreach(var s in GetAllFieldsWithAttribute(typeof(ShouldBeInitializedAttribute))) 

你可以讓這整個應用的實用性:

private IEnumerable<FieldInfo> GetAllFieldsWithAttribute(Type attributeType) 
{ 
    return this.GetType().GetFields().Where(
     f => f.GetCustomAttributes(attributeType, false).Any()); 
} 

然後改變您的來電:

public static IEnumerable<FieldInfo> GetAllFieldsWithAttribute(this Type objectType, Type attributeType) 
{ 
    return objectType.GetFields().Where(
     f => f.GetCustomAttributes(attributeType, false).Any()); 
} 

你可以這樣稱呼:

this.GetType().GetAllFieldsWithAttribute(typeof(ShouldBeInitializedAttribute)) 

編輯:要獲得私有字段,改變GetFields()到:

GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 

而得到的類型(你的循環內):

object o = s.GetValue(this); 
+0

我怎樣才能得到這些領域的價值?此外,奇怪的是,基類似乎只有在宣佈公開的時候纔會看到孩子的領域 - 我嘗試了保護和內部,但這只是忽略了他們。 – 2013-03-25 17:57:50

+0

@golergka,看我的編輯。 – 2013-03-25 18:29:14