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

时间:2013-02-19 14:53:05

标签: c#

来自C#4.0第7.5.5节。

  

如果M是在值类型中声明的实例函数成员:

     
      
  • [...]
  •   
  • 如果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;
        }
}

1 个答案:

答案 0 :(得分:5)

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

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

问题在于我的句子片段“值类型的只读字段”含糊不清且具有误导性。我打算将它表示 class 中的只读字段,其中字段是值类型S ,但显然更自然的读取是将其作为只读字段在S本身。我应该完全改写这句话。为错误道歉。

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