out
或ref
(因为这会更改引用,而不是对象).因此,程序员知道,如果string x = "abc"
在方法的开头,而这在方法的主体中没有改变,那么x == "abc"
在方法的结尾."abc" == "ab" + "c"
.虽然这并不需要不变性,但对这样一个字符串的引用在其整个生命周期内始终等于"abc"(这确实需要不变性),这一事实使得在保持与以前的值相等至关重要的情况下,可以将其用作键,从而更容易确保正确性(字符串确实常用作键).Christmas.AddMonths(1)
产生一个新的DateTime
而不是改变一个可变的DateTime
是有意义的.(另一个示例,如果我作为一个可变对象更改了我的名称,那么更改的是我使用的名称,"Jon"保持不变,而其他Jon不会受到影响.return this
个克隆.由于副本无论如何都无法更改,所以假装某个东西是它自己的副本是安全的.总的来说,对于那些目的中没有经历变化的对象来说,保持不变有很多好处.主要的缺点是需要额外的构造,尽管即使在这里也常常被夸大(请记住,在StringBuilder变得比具有其固有构造的等效串联序列更高效之前,您必须进行几个附加).
如果可变性是一个对象(希望由一个工资永远不会改变的雇员对象建模)的目的的一部分,这将是一个缺点,尽管有时即使这样,它也会很有用(在许多web和其他无状态应用程序中,执行读取操作的代码与执行更新的代码是分开的,使用不同的对象可能是自然的——我不会让一个对象不可变,然后强制使用该模式,但如果我已经有了该模式,我可能会让我的"读取"对象不可变,以获得性能和正确性保证增益).
抄写是一种中间立场.这里的"real"类包含对"state"类的引用.状态类在复制操作中共享,但如果更改状态,则会创建状态类的新副本.这比C++更常用于C++,这就是为什么它是STD:String拥有一些但不是全部的不变类型的优点,同时保持不变.