我正在阅读Eric关于突变只读结构的博客,我在这里看到了许多关于这个博客的引用,作为一个论点,为什么值类型必须是不可变的。但还有一件事还不清楚,即当您访问值类型时,您总是得到它的副本,下面是示例:
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());
}
}问题是,为什么当我改变
public readonly Mutable m = new Mutable();至
public Mutable m = new Mutable();一切都开始正常运转,这是人们所期待的。
请您解释一下为什么值类型必须是不可变的。我知道它对线程安全很好,但在这种情况下,同样可以应用于引用类型。
发布于 2011-07-04 09:40:29
具有变异方法的结构在几种情况下表现得很奇怪。
您已经发现的示例是一个只读字段。防御性复制是必要的,因为您不想修改只读字段。
但也被用作财产。再次发生隐式复制,并且只有副本发生变异。即使财产有一个策划人。
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 :(
}这表明变异方法在结构上是有问题的。但是,它并不表明具有setter的公共字段或属性的可变结构是有问题的。
发布于 2011-07-04 09:12:12
螺纹安全是一个明显的技术原因.它适用于值类型以及引用类型(参见System.String)。
更普遍的准则“值类型应该是不变的”是不同的。它是关于代码的可读性,主要来源于可变值可能造成的混乱。这个代码片段只是一个例子。大多数人不会期待1,1,1的结果。
发布于 2011-07-04 09:14:18
我不认识C#,所以我会试着回答你问题的第二部分。
为什么值类型必须是不可变的?
从领域驱动设计的角度来看,有两种类型的对象:
如果值类型是可变的,那么想象一下,如果更改数字2:2 == 1+1的值不被保证为真,会发生什么。
有关更多信息,请参见这些链接:
https://stackoverflow.com/questions/6569238
复制相似问题