Reputation: 2914
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
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
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
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
Reputation: 5113
You can only use reflection
typeof(MyClass)
.GetField("name",BindingFlags.Instance|BindingFlags.NonPublic)
.SetValue(myclassInstance, 123);
Upvotes: 3
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
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