Modify private readonly member variable?

大兔子大兔子 提交于 2019-12-08 01:20:45

问题


I have the following code :

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");
    }
}

Is there any way I can change the value of mc.name without modifying the class?


回答1:


You can only use reflection

typeof(MyClass)
   .GetField("name",BindingFlags.Instance|BindingFlags.NonPublic)
   .SetValue(myclassInstance, 123);



回答2:


With reflection, yes ( Can I change a private readonly field in C# using reflection? ), but there's probably a very good reason why the variable is set to private readonly.




回答3:


I would hope not. Reflection may let you do it - I can't remember offhand whether it obeys readonly-ness or not.

But you really shouldn't try to do this... if something is readonly, other parts of the code may well depend on it not changing.




回答4:


You can do this using reflection. I could post an example, but there's already a really good one over here:

http://dotnetproject.blogspot.com/2008/03/systemreflection-how-to-access-and.html

But I'd really take a long, hard look at the logic that got you to the point where you think you need to do this. You are "cutting against the grain" with regards to how the class was designed, and there could be many unexpected behaviors pop up once you start tinkering with private fields. The developer/architect had a reason for making them read-only, and probably relies on them being immutable after instantiation.

"Just because we can do a thing, does not mean we should do a thing." - Roddenberry




回答5:


In the current implementation of .net you can modify it using private reflection. You first need to get the FieldInfo with BindingFlags.NonPublic|BindingFlags.Instance and the use it to change the value.

But I think another/future implementation is allowed to actually enforce readonly. For example a JITter might embed the value into the compiled code. This means your code might break in a future version of .net. So I recommend not relying on this behavior.


Example code:

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;}}



回答6:


According the MSDN specs you can only retrieve the public fields/members using reflection, so that path should not be possible.However you can specify your own binding flags to get around this. I haven't tried it though.

I'm not sure if it's doable in C#, but you could go unmanaged, and try to manipulate the memory directly. But I'm guessing this will end up in exceptions as Windows mostl likely will not allow this.



来源:https://stackoverflow.com/questions/7876333/modify-private-readonly-member-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!