2

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?

AstroCB
  • 12,337
  • 20
  • 57
  • 73
conectionist
  • 2,694
  • 6
  • 28
  • 50
  • [Eric Lippert's answer](http://facebook.stackoverflow.com/questions/6722571/c-sharp-and-immutability-and-readonly-fields-a-lie) to the opposite-side version of this question appears to answer this. – Raymond Chen Oct 24 '11 at 13:32
  • possible duplicate of [Can I change a private readonly field in C# using reflection?](http://stackoverflow.com/questions/934930/can-i-change-a-private-readonly-field-in-c-sharp-using-reflection) – Oskar Kjellin Oct 24 '11 at 13:32
  • 2
    If you're truly evil you can even change `String.Empty`. But don't expect anything to work after that. – CodesInChaos Oct 24 '11 at 13:48

6 Answers6

4

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.

Community
  • 1
  • 1
Adam Flanagan
  • 3,052
  • 23
  • 31
3

You can only use reflection

typeof(MyClass)
   .GetField("name",BindingFlags.Instance|BindingFlags.NonPublic)
   .SetValue(myclassInstance, 123);
Mohamed Abed
  • 5,025
  • 22
  • 31
2

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Just tested it, the current implementation allows this. But from what I remember the spec allows implementations where `readonly` will never change. – CodesInChaos Oct 24 '11 at 13:38
  • @JonSkeet Aparently it does. But this is just out of curiosity. I realize probably shouldn't modify something like that. – conectionist Oct 24 '11 at 14:19
1

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;}}
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
1

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

Wesley Long
  • 1,708
  • 10
  • 20
0

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.

codingbunny
  • 3,989
  • 6
  • 29
  • 54