[英]C# - Set Property of a Property with Reflection
SO Community,所以社区,
So I'm learning C# and am still trying to wrap my head around reflection.所以我正在学习 C# 并且仍在努力思考。 In particular trying to use it to access a property of a property on a class.
特别是尝试使用它来访问 class 上的属性。
I've boiled down the basic task that I'm trying to accomplish below:我在下面总结了我要完成的基本任务:
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
}
}
}
edit 1 :编辑 1 :
At Yair Nevet's suggestion I'm grabbing the FieldInfo from the applicable object like,在Yair Nevet 的建议下,我从适用的 object 中获取 FieldInfo,例如,
FieldInfo fieldInfo = needToReflect.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
But from there I get hung up on accessing and setting the right 'State' Field/Property on that member field但是从那里我挂断了在该成员字段上访问和设置正确的“状态”字段/属性
Solution (ie. here's what I plugged in on that TODO comment):解决方案(即,这是我在该 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;
That does it.就是这样。 Thanks to Shlomi Borovitz for pointing me in the right direction.
感谢Shlomi Borovitz为我指明了正确的方向。
Thanks!谢谢!
You are trying to access a Property while the member is actually a private Field : 当成员实际上是私有字段时,您正在尝试访问属性 :
propertyName = String.Format("MyObject{0}",idx);
Use GetField
method instead for that: 使用
GetField
方法代替:
needToReflect.GetType().GetField(propertyName, BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
The FieldInfo
object which returned by GetField
has property which called FieldInfo
, which returns the type of that field. 由
GetField
返回的FieldInfo
对象具有名为FieldInfo
属性,该属性返回该字段的类型。 And you can query it for that type's (the type of the field) properties/fields (and whatever you want) - and get/set them. 您可以查询该类型的(字段的类型)属性/字段(以及您想要的任何内容)-并获取/设置它们。
Remember that both GetType
method (of any object), and the FieldInfo.FieldType
property return Type
object, that you can query in reflection. 请记住,(任何对象的)
GetType
方法和FieldInfo.FieldType
属性都返回Type
对象,您可以在反射中进行查询。
object obj =...
var field = obj.GetType().GetField(fieldName,...);
field.FieldType.GetField(...
//etc... etc...
For each field, you can query the type and for each type, you can query the fields, and get/set them. 对于每个字段,您可以查询类型,对于每种类型,您可以查询字段,并获取/设置它们。
BTW, in C# 4.0 you can use the dynamic
pseudo type (it used as a type when declaring dynamic variable, but it's not a real type), and then using that variable, while assuming which properties/fields/methods that variable would have in runtime (ie, using them like they are known in compile time although they don't). 顺便说一句,在C#4.0中,您可以使用
dynamic
伪类型(在声明动态变量时用作类型,但它不是实型),然后使用该变量,同时假定该变量将具有哪些属性/字段/方法。运行时(即使用它们,就像它们在编译时一样,尽管它们不是)。 This will not work for private members (and I can't warn you enough against calling private members in reflection), but for public members, this would make your code simple and readable, like you never used reflection (although, behind the scenes [in this case] reflection would be used). 这不适用于私有成员(并且我不能警告您不要在反射中调用私有成员),但是对于公共成员,这将使您的代码简单易读,就像您从未使用过反射(尽管在幕后[在这种情况下]将使用反射)。
完成这些步骤...
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.
Given:鉴于:
class ClassyMcClass
{
public int PropertyB { get; set; }
}
class MyClass
{
public ClassyMcClass PropertyA { get; set; }
}
The following code uses reflection on a MyClass
object to set the int value of PropertyB
in PropertyA
to NewValue
:以下代码使用
MyClass
object 上的反射将PropertyB
中PropertyA
的 int 值设置为NewValue
:
PropertyInfo propA = typeof(MyClass).GetProperty("PropertyA");
PropertyInfo probBofA = propA.PropertyType.GetProperty("PropertyB");
// Set property B of property A, where obj is of type MyClass
probBofA.SetValue(propA.GetValue(obj), NewValue, null);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.