修改私有readonly成员变量?
我有以下代码:
public class MyClass { private readonly string name; public string Name { get { return name; } } public MyClass(string name) { this.name = name; } } class Program { static void Main(string[] args) { MyClass mc = new MyClass("SomeName"); } }
有没有什么办法可以在不修改类的情况下更改mc.name的值?
你只能使用reflection
typeof(MyClass) .GetField("name",BindingFlags.Instance|BindingFlags.NonPublic) .SetValue(myclassInstance, 123);
使用reflection ,是( 我可以使用reflection 更改C#中的私有只读字段吗? ),但可能有一个非常好的理由将变量设置为private readonly
。
我希望不会。 反思可能会让你这样做 – 我不记得它是否服从于只读。
但是你真的不应该尝试这样做……如果某些东西是只读的,那么代码的其他部分很可能依赖于它不会改变。
你可以使用reflection来做到这一点。 我可以发一个例子,但这里已经有一个非常好的了:
http://dotnetproject.blogspot.com/2008/03/systemreflection-how-to-access-and.html
但是我真的需要经过长时间的努力研究才能让你认为自己需要做到这一点。 关于课程的设计方式,你“正在减少攻击”,一旦开始修补私人领域,就会出现许多意想不到的行为。 开发人员/架构师有理由将它们设置为只读,并且可能依赖于它们在实例化后是不可变的。
“仅仅因为我们可以做一件事,并不意味着我们应该做一件事。” – 罗德伯里
在.net的当前实现中,您可以使用私有reflection来修改它。 首先需要使用BindingFlags.NonPublic|BindingFlags.Instance
获取FieldInfo
并使用它来更改值。
但我认为允许另一个/未来的实现实际上只执行readonly
。 例如,JITter可能会将值嵌入到已编译的代码中。 这意味着您的代码可能会在.net的未来版本中中断。 所以我建议不要依赖这种行为。
示例代码:
void Main() { this.GetType() .GetField("name", BindingFlags.NonPublic | BindingFlags.Instance) .SetValue(this, "Yes"); Name.Dump(); } private readonly string name="No"; public string Name{get{return name;}}
根据MSDN规范,您只能使用reflection检索公共字段/成员,因此该路径不可能。但是,您可以指定自己的绑定标志来解决此问题。 我没有尝试过。
我不确定它在C#中是否可行,但你可以不受管理,并尝试直接操作内存。 但我猜这将最终出现exception,因为Windows最有可能不允许这样做。