关于c#:如何在构造后修改值类型中的只读字段


How to modify a readonly field in a value-type after construction

来自C 4.0第7.5.5节。

If M is an instance function member declared in a value-type:

  • [...]
  • If E is not classified as a variable, then a temporary local variable of E's type is created and the value of E is assigned to the
    variable. E is then reclassified as a reference to that temporary
    local variable. The temporary variable is accessible as this within
    M, but not in any other way. Thus, only when E is a true variable
    (what is a true variable...?) is it possible for the caller to observe the changes that
    M makes to this.

埃里克·利珀特接着说:

This point illustrates yet another way in which the combination of
mutability and copy-by-value semantics can lead to trouble. For
example, a readonly field is not classified as a variable after the
constructor runs. Therefore, an attempt to call a method that mutates
the contents of a readonly field of a value type succeeds but actually
mutates a copy! Avoid these problems by avoiding mutable value types
altogether.

我怎样才能重现埃里克描述的场景?我尝试了以下方法。如我所料,它出错了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    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;
        }
}

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

Mutating readonly structs

问题是我的句子片段"一个值类型的只读字段"不明确且容易误导。我的意思是在类中的只读字段,其中字段的值类型为s,但显然更自然的读取方式是将其作为s本身的只读字段。我应该把这句话重编一遍。为这个错误道歉。

回答你的另一个问题:形容词"真"是不必要的。如果它只是说"因此,只有当e是变量时,调用者才可能观察m对此所做的更改",那么这个句子同样正确。