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 的内容 - 或者至少在我看来是这样)。这可能吗?

4

1 回答 1

2

你可以用一个简单的表达式得到这个:

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

然后将您的呼叫更改为:

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

您可以通过将其设置为以下扩展方法,使其在整个应用程序中更有用Type

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);
于 2013-03-25T17:38:54.753 回答