早上好,下午或晚上,
假设我有一个班级
public class SomeClass
{
uint SomeField1;
uint[] SomeField2;
(...)
}
和一系列不可变的对象A1
,A2
,...
类型SomeClass
不同,例如 only < / em> by SomeField1
,将SomeField2
设置为指向内存中相同位置的所有内容是一个好习惯,还是应该在构造函数中使用数组复制,即使我知道对象是不可变?
非常感谢。
答案 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)如果有人试图违反只读的例外,那就是例外。