conectionist
conectionist

Reputation: 2914

Modify private readonly member variable?

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?

Upvotes: 2

Views: 3804

Answers (6)

CodesInChaos
CodesInChaos

Reputation: 108790

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

Upvotes: 1

Wesley Long
Wesley Long

Reputation: 1708

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

Upvotes: 1

Noel Frostpaw
Noel Frostpaw

Reputation: 3999

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.

Upvotes: 0

Mohamed Abed
Mohamed Abed

Reputation: 5113

You can only use reflection

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

Upvotes: 3

Adam Flanagan
Adam Flanagan

Reputation: 3052

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.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1500055

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.

Upvotes: 2

Related Questions