修改私有只读成员变量?
我有以下代码:
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 的值?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
通过反射,是的(我可以使用以下命令更改 C# 中的私有只读字段吗反射?),但是将变量设置为
private readonly
可能有一个很好的理由。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
.只能使用反射
You can only use reflection
我希望不会。反射可能让你做到这一点 - 我不记得它是否遵守只读性。
但你真的不应该尝试这样做......如果某些内容是只读的,代码的其他部分很可能依赖于它不改变。
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.
您可以使用反射来做到这一点。我可以发布一个示例,但这里已经有一个非常好的示例:
http://dotnetproject.blogspot.com/2008/03/systemreflection-how-to-access-and.html
但我真的会仔细研究一下逻辑让你到了你认为你需要这样做的地步。关于类的设计方式,您“违背了原则”,一旦您开始修改私有字段,可能会出现许多意想不到的行为。开发人员/架构师有理由将它们设置为只读,并且可能依赖于它们在实例化后不可变。
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.
在 .net 的当前实现中,您可以使用私有反射来修改它。您首先需要使用
BindingFlags.NonPublic|BindingFlags.Instance
获取FieldInfo
并使用它来更改值。但我认为允许另一个/未来的实现实际上强制执行只读。例如,JITter 可能会将值嵌入到已编译的代码中。这意味着您的代码可能会在 .net 的未来版本中损坏。所以我建议不要依赖这种行为。
示例代码:
In the current implementation of .net you can modify it using private reflection. You first need to get the
FieldInfo
withBindingFlags.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:
根据 MSDN 规范,您只能使用反射检索公共字段/成员,因此该路径不应该是可能的。但是您可以指定自己的绑定标志来解决此问题。不过我还没试过。
我不确定它在 C# 中是否可行,但您可以采用非托管方式,并尝试直接操作内存。但我猜测这最终会出现异常,因为 Windows 很可能不允许这样做。
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.