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 に答える