[英]C# - Set Property of a Property with Reflection
所以社區,
所以我正在學習 C# 並且仍在努力思考。 特別是嘗試使用它來訪問 class 上的屬性。
我在下面總結了我要完成的基本任務:
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 的建議下,我從適用的 object 中獲取 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為我指明了正確的方向。
謝謝!
當成員實際上是私有字段時,您正在嘗試訪問屬性 :
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中,您可以使用dynamic
偽類型(在聲明動態變量時用作類型,但它不是實型),然后使用該變量,同時假定該變量將具有哪些屬性/字段/方法。運行時(即使用它們,就像它們在編譯時一樣,盡管它們不是)。 這不適用於私有成員(並且我不能警告您不要在反射中調用私有成員),但是對於公共成員,這將使您的代碼簡單易讀,就像您從未使用過反射(盡管在幕后[在這種情況下]將使用反射)。
完成這些步驟...
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.
鑒於:
class ClassyMcClass
{
public int PropertyB { get; set; }
}
class MyClass
{
public ClassyMcClass PropertyA { get; set; }
}
以下代碼使用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.