2013-03-25 40 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