修改私有只读成员变量



我有以下代码:

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

使用反射,是的(我可以在c#中使用反射更改私有只读字段吗?),但是将变量设置为private readonly可能有一个很好的理由。

你只能使用反射

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

我希望不是。反射可能让你这样做——我不能马上记住它是否服从合理性。

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

您可以使用反射来做到这一点。我可以贴一个例子,但是这里已经有一个很好的例子了:

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

但我真的会花很长时间,仔细看看你认为你需要这样做的逻辑。关于类是如何设计的,你是在"违背常规",一旦你开始修改私有字段,可能会出现许多意想不到的行为。开发人员/架构师将它们设置为只读是有原因的,并且可能依赖于它们在实例化后是不可变的。

"仅仅因为我们能做一件事,并不意味着我们应该做一件事。"——Roddenberry

在当前的。net实现中,你可以使用私有反射来修改它。您首先需要获得FieldInfoBindingFlags.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;}}

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

我不确定它在c#中是否可行,但你可以去非托管,并尝试直接操作内存。但是我猜测这将以异常告终,因为Windows很可能不允许这样做。

最新更新