[英]Set readonly property value through reflection
我需要修改僅具有“ get”選項的屬性值。 我發現使用GetField有一些技巧,但是沒有成功。
參見下面的代碼:
namespace ConsoleApplication1
{
abstract class Test
{
private int testValue;
protected int TestValue {
get { return testValue; }
}
}
class Myclass : Test
{
public Myclass(): base(){}
}
class Program
{
static void Main(string[] args)
{
Myclass test = new Myclass();
var field = typeof(Myclass).GetField("<TestValue>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(test, 3);
}
}
}
實際上,我想將“ TestValue”設置為值3,但它不起作用。 我可能做錯了。
您找到的“技巧”依賴於自動實現的屬性( string Foo { get; }
),這些屬性會編譯為帶有后備字段的屬性(因此,您要查找的成員的名稱)。 請注意,這非常脆弱,因為未記錄生成的成員名稱。 但是,從一開始就依靠反射來訪問類型的成員是脆弱的。
但是,您沒有自動實現的屬性,您只需要訪問該屬性公開的名為testValue
的私有字段testValue
。
但是GetField()
不處理非公共成員的繼承,因此請參見派生類型的GetFields 。 此方法將幫助您:
public static void Main()
{
Myclass test = new Myclass();
var field = GetInheritedPrivateField(test.GetType(), "testValue");
field.SetValue(test, 3);
}
private static FieldInfo GetInheritedPrivateField(Type type, string fieldName)
{
do
{
var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
{
return field;
}
type = type.BaseType;
}
while (type != null);
return null;
}
您可以檢索Test
類的字段信息,並使用它來設置派生類實例上的值,如下所示:
var field = typeof(Test).GetField("testValue", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(test, 3);
沒有“設置者”,就無法為屬性設置值。
如果您不希望該屬性被范圍外的其他對象覆蓋,則可以使用“ private set”作為設置器,然后可以在范圍內設置值。
另一種方法是編寫一種方法來設置屬性的getter值。 即
class Myclass : Test
{
public Myclass(): base(){}
public void SetValue(int value) { this.testValue=value; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.