修改私有readonly成员变量?

时间:2011-10-24 13:28:12

标签: c# readonly private-members

我有以下代码:

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的值?

6 个答案:

答案 0 :(得分:4)

使用reflection,是(Can I change a private readonly field in C# using reflection?),但可能有一个很好的理由将变量设置为private readonly

答案 1 :(得分:3)

您只能使用反射

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

答案 2 :(得分:2)

我希望不会。反思可以让你这样做 - 我不记得它是否服从了readonly-ness。

但是你真的不应该尝试这样做......如果某些内容是只读的,那么代码的其他部分可能很大程度上取决于它不会改变。

答案 3 :(得分:1)

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

但我认为允许另一个/未来的实施实际执行readonly。例如,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;}}

答案 4 :(得分:1)

您可以使用反射来完成此操作。我可以发一个例子,但这里已经有一个非常好的了:

http://dotnetproject.blogspot.com/2008/03/systemreflection-how-to-access-and.html

但我真的需要经过长时间的努力研究才能让你认为自己需要做到这一点。关于课程的设计方式,你“正在减少”,并且一旦你开始修改私人领域,就会出现许多意外行为。开发人员/架构师有理由将它们设为只读,并且可能依赖于实例化后它们是不可变的。

  

“仅仅因为我们可以做一件事,并不意味着我们应该做一件事。” - Roddenberry

答案 5 :(得分:0)

根据MSDN规范,您只能使用反射检索公共字段/成员,因此该路径不可行。但是,您可以指定自己的绑定标记来解决此问题。我没试过。

我不确定它在C#中是否可行,但您可以不受管理,并尝试直接操作内存。但我猜测这将最终出现在异常中,因为Windows最不可能允许这样做。