1

これは私がやりたいことです。それが可能かどうかはわかりません。または、間違った方法で問題を攻撃している可能性があります。

メンバーがカスタム属性を持つオブジェクトがあり、その属性の情報を使用してコレクション内の値を検索し、リフレクションを使用してその特定のプロパティの値を設定しています。しかし、私のタイプには、単純な文字列や整数ではなく、値を設定するための情報を持つ属性を持つクラスである、より複雑なメンバーがいくつかあります。

したがって、リフレクションを使用して値を設定するには、変更するオブジェクトのインスタンスが必要なので、私の質問は次のとおりです。

実際のメンバーを取得して、属性を使用してその値を調べて取得するにはどうすればよいですか?

ここに私が持っているものと私が欲しいもののいくつかのサンプルコードがあります:

public class MyEntity
{
    [CustomAttribute("Info to Set Values")]
    public string SimpleProperty {get;set;}

    public MyOtherClass ComplexProperty {get;set;}

    public static bool SetSimpleValueTypes(object instance, IEnumerable<Value> values){
        var mappedProperties = instance.GetType()
                                   .GetProperties()
                                   .Where(type => type.GetCustomAttributes(typeof(CustomAttribute), true).Length > 0);

        foreach (PropertyInfo property in mappedProperties)
        {
           /*...and then some code to get the Value to set in the property*/
           var value = GetValue(values);
           property.SetValue(instance, value, null);
        }
    }

}

public class MyOtherClass
{
    [CustomAttribute("Info to Set Values")]
    public string SimpleInnerProperty {get;set;}
}

上記のコードでは、メソッド SetSimpleValueTypes で、CustomAttribute を持つプロパティを持つ特定のインスタンスのすべてのプロパティを取得してから、これらの PropertyInfo を反復し、渡したインスタンスを使用して値を設定します。次のように使用します。

MyEntity entity = new MyEntity();
MyEntity.SetSimpleValueTypes(entity, valuesFromSomeWhere);

これにより、string、int などの単純な型のすべてのプロパティの値が正しく設定されます。しかし今、ComplexProperty の値も設定する必要があるため、それほど柔軟ではないアプローチを使用して、次のことができます。

MyEntity entity = new MyEntity();
MyEntity.SetSimpleValueTypes(entity, valuesFromSomeWhere);
MyEntity.SetSimpleValueTypes(entity.ComplexProperty, valuesFromSomeWhere);

したがって、ComplexProperty を明示的に呼び出して SetSimpleValueTypes メソッドに渡すのではなく、MyEntity のプロパティを繰り返しスローし、複合値が見つかったら複合の実際のインスタンスを渡したいと思います。メソッドに入力して、そのプロパティを反復し、そのインスタンスで値を設定できるようにします。

これで質問がもう少し明確になることを願っています。:)

前もって感謝します!

4

1 に答える 1

2

書かれているように、メソッドの実行時に MyEntity オブジェクトにはおそらく値が設定されていませんComplexPropertyよね? ヌルになるだけです。MyOtherClassしたがって、 (Activator.CreateInstance()たとえば、またはおそらく DI フレームワークを使用して)の新しいインスタンスを作成し、そのオブジェクトでもメソッドを再帰的に呼び出す必要があります。

public static bool SetValueTypes(object instance, IEnumerable<Value> values){
    var mappedProperties = instance.GetType()
                               .GetProperties()
                               .Where(type => type.GetCustomAttributes(typeof(CustomAttribute), true).Length > 0);

    foreach (PropertyInfo property in mappedProperties)
    {
       /*...and then some code to get the Value to set in the property*/
       var value = GetValue(values);
       property.SetValue(instance, value, null);
    }

    var complexProperties = instance.GetType()
                               .GetProperties()
    // Either assume that unmapped properties are all complex,
    // or use your own criteria. Maybe anything whose type is
    // a class and not a string?
                               .Where(type => type.GetCustomAttributes(typeof(CustomAttribute), true).Length == 0);
    foreach (PropertyInfo property in mappedProperties)
    {
       var value = Activator.CreateInstance(property.PropertyType);
       SetValueTypes(value, values);
       property.SetValue(instance, value, null);
    }

}
于 2012-08-21T23:01:31.760 に答える