C#-设置具有反射的属性的属性

C#-设置具有反射的属性的属性,c#,reflection,C#,Reflection,所以社区, 所以我正在学习C#,并且仍然试图将我的头脑集中在思考上。特别是尝试使用它访问类上属性的属性 我已将我试图完成的基本任务概括如下: public enum SIGNAL_STATE { NOT_RETRIEVED = 0, RETRIEVING = 1, RETRIEVED = 2, FAILED = 3 } public class MyObjectClass { public string MyString; private SIGNAL_STATE _state

所以社区,

所以我正在学习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

        }
    }
}
但从那以后,我就无法访问和设置该成员字段上正确的“State”字段/属性

解决方案(即,以下是我插入的待办事项评论):

就这样。感谢Shlomi Borovitz为我指明了正确的方向


谢谢

完成这些步骤

1)获取类型。

2)具有该类型的实例。

3)获取属性的属性信息。

4)对PropertyInfo对象调用“GetSetMethod”。它将返回一个MethodInfo对象。


5)使用类型实例和值调用MethodInfo对象。

您试图访问属性,而成员实际上是一个私有字段

propertyName = String.Format("MyObject{0}",idx);
请使用
GetField
方法:

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

GetField
返回的
FieldInfo
对象具有名为
FieldInfo
的属性,该属性返回该字段的类型。 您可以查询该类型(字段类型)的属性/字段(以及您想要的任何内容),并获取/设置它们

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

object obj =... 
var field = obj.GetType().GetField(fieldName,...);
field.FieldType.GetField(... 
//etc... etc... 
对于每个字段,可以查询类型;对于每个类型,可以查询字段,并获取/设置字段

顺便说一句,在C#4.0中,您可以使用
动态
伪类型(它在声明动态变量时用作类型,但不是实类型),然后使用该变量,同时假设该变量在运行时将具有哪些属性/字段/方法(即,使用它们就像在编译时已知一样,尽管它们不知道)。
这对私有成员不起作用(我无法警告您不要在反射中调用私有成员),但对于公共成员,这将使您的代码简单易读,就像您从未使用过反射一样(尽管在幕后[在本例中]会使用反射)

有趣的是,这可能是我的灵丹妙药。我现在把它插入我的精简示例应用程序,看看我能用它做些什么谢谢你的帮助。这非常接近。假设我从您的建议中返回了
FieldInfo
。然后,要设置该字段的属性(或者应该是该字段的字段?),如何找到需要设置的对象的实例。ie:
fieldInfo.FieldType.GetProperty(“State”).SetValue(##缺少此实例##,信号状态。正在检索,null)如果你还在学习C#,我建议你以后深入思考。。。记住它就在那里,记住它的用途——让它在你控制C#时使用。然后记住,它有很多缺点-所以在使用它之前要仔细考虑这是一个很好的建议。。。但遗憾的是,正如经常发生的那样,我发现自己支持这种特殊设计模式至关重要的代码。。。更像是反模式,或者。。。必要的evil@darkpbj+1用完整的解决方案更新你的答案。酷,这让我更接近。假设我做一个
FieldInfo stateFieldInfo=FieldInfo.FieldType.GetField(“_state”,…)
(启用
SetField
BindingFlag)如果我执行
stateFieldInfo.SetValue(…)
操作,我就不知道要为第一个参数传入什么。您需要获取字段的值,并将其作为第一个变量传递(想想看,这非常合乎逻辑),我已经更新了答案。您可能会发现更新非常有用:-)(希望)这是正确的答案,我花了一点时间才弄清楚具体的实现是什么样子。问题用我的四行代码更新。为了记录在案,我不会说这是一种反模式。如果说有什么的话,我认为它有某种民间的魅力,几乎接近优雅。我想我可以继续讨论最佳实践,但这是下一次的另一个话题。无论如何,谢谢!确切地说,在某些情况下,这是一种反模式。在另一些例子中,这只是必要的邪恶:)我是说,在看到并更正了使用反射模拟多态性的代码之后,不需要调用GetMethod/SetMethod。PropertyInfo对象上有GetValue/SetValue方法,您可以直接调用这些方法。
needToReflect.GetType().GetField(propertyName, BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
object obj =... 
var field = obj.GetType().GetField(fieldName,...);
field.FieldType.GetField(... 
//etc... etc...