C# - 用反射设置属性的属性

时间:2014-03-03 21:24:37

标签: c# reflection

SO社区,

所以我正在学习C#,我仍然试图围绕反思。特别是尝试使用它来访问类的属性的属性。

我已经完成了以下我要完成的基本任务:

public enum SIGNAL_STATE { NOT_RETRIEVED = 0, RETRIEVING = 1, RETRIEVED = 2, FAILED = 3 }

public class MyObjectClass
{
    public string MyString;
    private SIGNAL_STATE _state = SIGNAL_STATE.NOT_RETRIEVED;
    public SIGNAL_STATE State { get { return _state; } set { _state = value;} }
}

public class NeedToReflect
{
    private MyObjectClass _myObject1 = new MyObjectClass();
    private MyObjectClass _myObject2 = new MyObjectClass();
    private MyObjectClass _myObject3 = new MyObjectClass();

    public MyObjectClass MyObject1
    {
        get{return _myObject1;} 
        set{_myObject1 = value;}
    }

    public MyObjectClass MyObject2
    {
        get{return _myObject2;}
        set{_myObject2 = value;}
    }

    public MyObjectClass MyObject3
    {
        get{return _myObject3;}
        set{_myObject3 = value;}
    }

    public static void Main(string [] args){
        NeedToReflect needToReflect = new NeedToReflect();

        string fieldName;
        for(int idx = 1; idx<=3; ++idx)
        {
            fieldName = String.Format("MyObject{0}",idx);

            //TODO: set state of 'MyObject' values to SIGNAL_STATE.RETRIEVING

        }
    }
}

编辑1

Yair Nevet的建议中,我从适用的对象中抓取FieldInfo,

FieldInfo fieldInfo = needToReflect.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);

但是从那里我开始在该成员字段上访问并设置正确的“州”字段/属性

解决方案(即这是我在TODO评论中插入的内容):

// Determine what binding flags will give us proper access to our member field
BindingFlags bindFlags = BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance;
// Get the field for that field
FieldInfo fieldInfo = needToReflect.GetType().GetField(fieldName, bindFlags);
// Pass in the containing object that we're reflecting on to get an instance of the member field
MyObjectClass myField = (MyObjectClass) fieldInfo.GetValue(needToReflect);
// We can now directly access and edit the value in question
myField.State = SIGNAL_STATE.RETRIEVING;

就是这样。感谢 Shlomi Borovitz 让我指向正确的方向。

谢谢!

3 个答案:

答案 0 :(得分:1)

您正在尝试访问属性,而该成员实际上是私有字段

propertyName = String.Format("MyObject{0}",idx);

使用GetField方法代替:

needToReflect.GetType().GetField(propertyName, BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);

答案 1 :(得分:1)

FieldInfo返回的GetField对象具有调用FieldInfo的属性,该属性返回该字段的类型。 你可以查询它的类型(字段的类型)属性/字段(以及你想要的任何东西) - 并获取/设置它们。

请记住,GetType方法(任何对象)和FieldInfo.FieldType属性返回Type对象,您可以在反射中查询。

object obj =... 
var field = obj.GetType().GetField(fieldName,...);
field.FieldType.GetField(... 
//etc... etc... 

对于每个字段,您可以查询类型,对于每种类型,您可以查询字段,并获取/设置它们。

顺便说一下,在C#4.0中你可以使用dynamic伪类型(它在声明动态变量时用作类型,但它不是真正的类型),然后使用该变量,同时假设哪些属性/字段/变量在运行时会有的方法(即使用它们,就像它们在编译时已知,尽管它们没有)。 这对私人成员不起作用(我不能警告你反对私人成员反映),但对于公众成员来说,这会使你的代码变得简单易读,就像你从未使用过反射一样(尽管在幕后[在这种情况下,将使用反射)。

答案 2 :(得分:0)

完成以下步骤......

1) Get the Type.
2) Have an instance of that type.
3) Get the PropertyInfo for the property.
4) Call "GetSetMethod" on the PropertyInfo object. It will return a MethodInfo object.
5) Invoke the MethodInfo object using the instance of the type and a value.