如何在构造后修改值类型中的只读字段

P.B*_*key 2 c#

来自C#4.0第7.5.5节.

如果M是在value-type中声明的实例函数成员:

  • [...]
  • 如果E未被归类为变量,则创建E类型的临时局部变量,并将E的值分配给变量.然后将E重新分类为对该临时局部变量的引用.临时变量在M中可以访问,但不能以任何其他方式访问.因此,只有当E是真正的变量 (真正的变量是什么??)时,调用者才有可能观察到M对此做出的变化.

Eric Lippert接着说:

这一点说明了可变性和按值复制语义的组合可能导致麻烦的另一种方式.例如,在构造函数运行后,readonly字段不会被归类为变量.因此,尝试调用一个方法来改变值类型的只读字段的内容会成功,但实际上会改变副本!通过完全避免可变值类型来避免这些问题.

如何重现Eric描述的场景呢?我尝试了以下内容.它像我期望的那样出错:

    struct A
    {
        public readonly int mutableReadonlyField;

        public A(int originalValue)
        {
            mutableReadonlyField = originalValue;
        }

        public A MethodThatMutatesTheContentsOfAReadOnlyField(int mutate)
        {            
            this.mutableReadonlyField = mutate;//Constructor has run so mutableReadonlyField is a temporary local variable
            //ERROR: A readonly field cannot be assigned to (except in a constructor or a variable initializer)

            A newA = this;//Is this a true variable?
            return newA;
        }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 5

我在我的博客上给出了一个例子:

http://ericlippert.com/2008/05/14/mutating-readonly-structs/

问题是我的句子片段"值类型的只读字段"是模糊和误导的.我打算将它表示一个中的只读字段,其中字段的值为S类型,但显然更自然的读取是将其作为S本身的只读字段.我应该完全改写这句话.为错误道歉.

回答你的另一个问题:形容词"真实"是不必要的.如果它只是说"因此,只有当E是一个变量时,调用者才有可能观察到M对此做出的变化.