2

不明なオブジェクト内にプロパティを設定する必要があります。構造は次のようになります。

        ObjA.ObjB().ObjC.PropA = propValue;

ObjA は参照されたクラスからのものです。ObjB() はオブジェクト型であるため、ObjC は不明です。Reflection を使用することを考えましたが、この場合の正しい使用方法がわかりません。

        object objB = ObjA.ObjB();
        Type objBType = objB.GetType();
        System.Reflection.XXXInfo objCInfo = objBType.GetXXX("ObjC");

        Type objCType = objCInfo.GetType();
        System.Reflection.PropertyInfo PropAInfo = objCType.GetProperty("PropA");
        PropAInfo.SetValue(PropAInfo, propValue, null);

回答 (BigM に感謝):

        dynamic objAB = ObjA.ObjB(); 
        objAB.ObjC.PropA = propValue;
4

2 に答える 2

2

これはおそらくあなたのために働くはずです。

object objB = ObjA.ObjB();
Type objBType = objB.GetType();
System.Reflection.PropertyInfo objCInfo = objBType.GetProperty("ObjC");
object val = objCInfo.GetValue(objB);

Type objCType = val.GetType();
System.Reflection.PropertyInfo PropAInfo = objCType.GetProperty("PropA");
PropAInfo.SetValue(val, propValue, null);

ただし、生活を少し楽にするために、ここで少し再設計を行うことができると思います。たとえば、型について何も知らない場合は、 andから型を使用dynamicして返すことを検討できますが、そこにはパフォーマンス ヒットがあります。dynamicObjCPropA

一方、ジェネリックを使用できる方法があれば、生活がずっと楽になります。たとえば、プロパティ値を設定するここのコードは、そのメソッドがジェネリックである場合、おそらく型を定義できる可能性がありますがObjC、現在のスニペットではそれを推測することはできません。

于 2012-11-01T14:34:40.347 に答える
2

「不明な」プロパティを名前で取得および設定するのに役立つ、いくつかの一般的な拡張メソッドを次に示します。

public static class ReflectionHelpers
{
    public static bool TrySetProperty<TValue>(this object obj, string propertyName, TValue value)
    {
        var property = obj.GetType()
            .GetProperties()
            .Where(p => p.CanWrite && p.PropertyType == typeof(TValue))
            .FirstOrDefault(p => p.Name == propertyName);

        if (property == null)
        {
            return false;
        }

        property.SetValue(obj, value);
        return true;
    }

    public static bool TryGetPropertyValue<TProperty>(this object obj, string propertyName, out TProperty value)
    {
        var property = obj.GetType()
            .GetProperties()
            .Where(p => p.CanRead && p.PropertyType == typeof(TProperty))
            .FirstOrDefault(p => p.Name == propertyName);

        if (property == null)
        {
            value = default(TProperty);
            return false;
        }

        value = (TProperty) property.GetValue(obj);
        return true;
    }
}

そして使用例:

public class Program
{
    public static void Main()
    {
        var foo = new Foo
        {
            Bar = new Bar
            {
                HelloReflection = "Testing"
            }
        };

        string currentValue;
        if (foo.Bar.TryGetPropertyValue("HelloReflection", out currentValue))
        {
            Console.WriteLine(currentValue); // "Testing"
        }

        if (foo.Bar.TrySetProperty("HelloReflection", "123..."))
        {
            foo.Bar.TryGetPropertyValue("HelloReflection", out currentValue)

            Console.WriteLine(currentValue); // "123.."
        }
        else
        {
            Console.WriteLine("Failed to set value");
        }
    }
}

public class Foo
{
    public object Bar { get; set; }
}

public class Bar
{
    public string HelloReflection { get; set; }
}
于 2012-11-01T14:35:43.487 に答える