不可变值类型

NDe*_*per 7 .net c# clr

我正在阅读Eric Liperts关于Mutating Readonly Structs的博客,我在这里看到很多参考资料,作为一个论证为什么值类型必须是不可变的.但仍然有一点不清楚,说当你访问值类型时,你总是得到它的副本,这是一个例子:

struct Mutable
{
    private int x;
    public int Mutate()
    {
        this.x = this.x + 1;
        return this.x;
    }
}

class Test
{
    public readonly Mutable m = new Mutable();
    static void Main(string[] args)
    {
        Test t = new Test();
        System.Console.WriteLine(t.m.Mutate());
        System.Console.WriteLine(t.m.Mutate());
        System.Console.WriteLine(t.m.Mutate());
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是这就是我改变时的原因

public readonly Mutable m = new Mutable();
Run Code Online (Sandbox Code Playgroud)

public Mutable m = new Mutable();
Run Code Online (Sandbox Code Playgroud)

一切都开始工作es 预期.

请您更清楚地解释为什么值类型必须是不可变的.我知道它对线程安全有好处,但在这种情况下,同样可以应用于引用类型.

Cod*_*aos 4

具有变异方法的结构在多种情况下表现得很奇怪。

您已经发现的示例是只读字段。防御性副本是必要的,因为您不想改变只读字段。

而且当用作属性时也是如此。隐式复制再次发生,并且只有副本发生变异。即使财产有二传手。

struct Mutable
{
    private int x;
    public int Mutate()
    {
        this.x = this.x + 1;
        return this.x;
    }
}

Mutable property{get;set;}

void Main()
{
    property=new Mutable();
    property.Mutate().Dump();//returns 1
    property.Mutate().Dump();//returns 1 :(
}
Run Code Online (Sandbox Code Playgroud)

这表明变异方法在结构上是有问题的。但它并没有表明具有公共字段或具有设置器的属性的可变结构是有问题的。