关于不可变对象的另一个问题

时间:2011-03-13 17:56:42

标签: c# .net immutability

早上好,下午或晚上,

假设我有一个班级

public class SomeClass
{
    uint   SomeField1;
    uint[] SomeField2;

    (...)
}

和一系列不可变的对象A1A2...类型SomeClass不同,例如 only < / em> by SomeField1,将SomeField2设置为指向内存中相同位置的所有内容是一个好习惯,还是应该在构造函数中使用数组复制,即使我知道对象是不可变?

非常感谢。

4 个答案:

答案 0 :(得分:3)

“男人”Eric Lippert对此有一个great blog post,涵盖浅层与深层不变性和观察不变性,这似乎是你问题的核心。如果您在构造函数中使用了对数组的引用,并且没有创建自己的数组副本,那么您将只具有“浅层”不变性。

  

ints字段“浅薄”   不可改变的。你可以依靠它   在某种程度上是不变的,但是   一旦你到达有一个点   全部是对可变对象的引用   投注已经结束。

     显然与浅的相反   不变性是“深层”的不变性;   在一个深刻不可改变的对象中   永远不变。

在你的情况下,SomeField2也会有观察不变性:从任何调用者的角度来看,字段都是不可变的(前提是你没有像@Slaks指出的那样直接访问它) - 除非有人else会更改您引用的数组。如果您保证该数组永远不会改变您所需要的一切 - 这将是flyweight pattern的一个应用程序。

答案 1 :(得分:1)

使用不可变数据结构的一个主要原因是它们可以安全地共享数据。如果您的数组永远不会被公开并且它永远不会改变,那么无论如何,在其他需要相同数组的不可变对象之间共享它。

答案 2 :(得分:1)

在您的旧问题Is this a good practice of immutability?中,我已说过:

  

由于您知道其他阵列的内容永远不会改变,您可以直接使用它。如果你想在不引起任何问题的情况下,你甚至可以在你的类的几个实例之间共享一个数组实例

所以只要你能保证不变性共享实例没问题。

答案 3 :(得分:1)

如果您保证您的对象的任何消费者都不会改变该数组,那么您可以安全地重新使用该数组。然而,这似乎对我起火了。在这种情况下,我强烈倾向于使字段成为包裹数组的ReadOnlyCollection<uint>;这样你就可以得到(1)很清楚的“在代码”文档中这个集合是只读的,(2)如果有人试图违反只读的例外,那就是例外。