不变的collections品?

我在我的应用程序中创建了大多数基本类型,不可变。 但是collections品也应该是不可变的吗? 对我来说,这似乎是一个巨大的开销,除非我错过了什么。

我在谈论集合以保存Point3值等,可以在不同时间添加它们。 因此,如果集合中有1M值,并且您需要删除其中的1个,则必须重新创建相同的集合,对吧?

Eric Lippert在C#中有一系列关于Immutability的系列,如果你一直阅读它,他会实现几个不同的不可变集合:

  1. C#中的不变性第一部分:不变性的种类
  2. C#中的不变性第二部分:一个简单的不可变堆栈
  3. C#中的不变性第三部分:协变不可变栈
  4. C#中的不变性第四部分:一个不可变的队列
  5. C#中的不变性第五部分:LOLZ!
  6. C#中的不变性第六部分:一个简单的二叉树
  7. C#中的不变性第七部分:关于二叉树的更多信息
  8. C#中的不变性第八部分:关于二叉树的更多信息
  9. C#中的不变性第九部分:学术? 加上我的AVL树实现
  10. C#中的不变性第十部分:双端队列
  11. C#中的不变性第十一部分:一个工作的双端队列

不可变集合很棒,特别是如果您的应用程序已经利用了不可变类型或语义。

.NET刚刚发布了他们的第一个不可变集合 ,我建议你试试。

我最喜欢的collections技巧就是永远不会传递它们。 如果它们只存在于单个对象中,那么使它们成为不可变的几乎是无关紧要的(只要你的包含对象不改变它们就不会改变它们)。

通常你的collections代表什么? 这是一系列狗或一系列发票……

通常你可以用一组狗(Herd?neuter?)或一组发票(付费?)来做一些事情。几乎总有一些操作适用于整个对象列表 – 具有超出单数的function的操作invoice.pay()(例如,确保首先支付最重要的发票),没有围绕您的集合的类,实际上没有放置这些操作的位置。

有一些变量与你的集合相关联通常也是有意义的 – 再次没有包装器你总是把这些变量放在一些奇怪的不自然的位置。

一开始可能看起来很奇怪,但在你判断之前尝试几次。

我同意Eric关于为问题选择合适工具的评论。 当您的目标包括提供清晰的身份语义或使您的实现更易于在并行计算环境中使用时,不可变性会增加价值。 不可变性还可以通过允许优化(如缓存或透明代理)来帮助提高性能。

另一方面,不变性也会带来性能成本 – 特别是当您使用“写时复制”模式来模拟“更改”时。

你必须决定为什么你希望你的实体/集合是不可变的 – 这将有助于决定是否这样做。

如果你只是从开始或结束添加/删除你可能会作弊 – 但总的来说; 是的:暗示是您需要为每个更改创建一个新集合。

所以:你需要(有效地)改变集合吗? 如果是这样,并给出它们的大小:我很想看看同步访问(而不是让它们正确地不可变)。 看看lock (又名Monitor )。

查找表将构成一个体面的不可变集合。 它不需要改变大小,你想要它是静态的,所以它很容易查找棘手的计算。 如果你以后需要添加一些东西,那么我就不会为了不变性而烦恼,它会破坏目的。

这取决于您的程序编写/设计的样式。

只有在以函数式编程影响的风格编程时,不可变集合才有意义(命令式设计的程序不应该使用它们)。

就像在函数式语言中一样,您应该使用链接列表,然后可以在每个元素( cons )的O(1)中构建它们并在function上处理它们(递归,从列表构建新列表)。

当你的程序需要命令式集合(数组,向量/列表)时,保持它们是可变的。

您可以将公共接口定义为IEnumerable,但仍在实现中使用可变集合。

这一切都取决于谁在同时使用这些collections品。 字符串是不可变的,以防止boo-boo像两个线程试图同时删除第一个字符串。

如果您有一个集合,您可以在构建它之后添加项目,它不是不可变的