[英]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.