修改私有只读成员变量?

发布于 2024-12-11 17:44:50 字数 412 浏览 0 评论 0原文

我有以下代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

黯然#的苍凉 2024-12-18 17:44:50

通过反射,是的(我可以使用以下命令更改 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.

小…红帽 2024-12-18 17:44:50

只能使用反射

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

You can only use reflection

typeof(MyClass)
   .GetField("name",BindingFlags.Instance|BindingFlags.NonPublic)
   .SetValue(myclassInstance, 123);
谁人与我共长歌 2024-12-18 17:44:50

我希望不会。反射可能让你做到这一点 - 我不记得它是否遵守只读性。

但你真的不应该尝试这样做......如果某些内容是只读的,代码的其他部分很可能依赖于它不改变。

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.

胡渣熟男 2024-12-18 17:44:50

您可以使用反射来做到这一点。我可以发布一个示例,但这里已经有一个非常好的示例:

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.

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

飘过的浮云 2024-12-18 17:44:50

在 .net 的当前实现中,您可以使用私有反射来修改它。您首先需要使用 BindingFlags.NonPublic|BindingFlags.Instance 获取 FieldInfo 并使用它来更改值。

但我认为允许另一个/未来的实现实际上强制执行只读。例如,JITter 可能会将值嵌入到已编译的代码中。这意味着您的代码可能会在 .net 的未来版本中损坏。所以我建议不要依赖这种行为。


示例代码:

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

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;}}
吐个泡泡 2024-12-18 17:44:50

根据 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文