7

根据 FxCop 的建议和我的个人倾向,我一直在鼓励我正在执教的团队尽可能地使用 ReadOnlyCollections。如果只是这样列表的收件人不能修改他们的内容。在他们的理论中,这是面包和黄油。问题是 List<> 接口更丰富地公开了各种有用的方法。他们为什么做出这样的选择?

您是否只是放弃并返回可写集合?您是否返回只读集合,然后将它们包装在可写品种中?啊啊啊。


更新:谢谢我熟悉框架设计指南,这就是团队使用 FxCop 来执行它的原因。然而,这个团队正在使用 VS 2005(我知道,我知道),所以告诉他们 LINQ/Extension 方法可以解决他们的问题,这让他们很难过。

他们了解到 List.FindAll() 和 .FindFirst() 比编写 foreach 循环更清晰。现在我正在推动他们使用 ReadOnlyCollections 他们失去了这种清晰度。

也许有一个我没有发现的更深层次的设计问题。

-- 对不起,原帖应该提到了 VS2005 的限制。我住了这么久,我只是没有注意到。

4

4 回答 4

7

.NET Framework 设计指南第二版的第 8.3.2 节:

务必使用ReadOnlyCollection<T>、 的子类ReadOnlyCollection<T>,或者在极少数情况下IEnumerable<T>用于表示只读集合的​​属性或返回值。

我们使用 ReadOnlyCollections 来表达我们返回集合的意图。

List<T>为方便起见,您所说的方法已添加到 .NET 2.0 中。在 C# 3.0 / .NET 3.5 中,您可以使用扩展方法(也可以使用 LINQ 运算符)重新启用所有这些方法ReadOnlyCollection<T>(或任何IEnumerable<T>方法),因此我认为没有任何动机将它们本地添加到其他类型。由于扩展方法的存在现在可用但不在 2.0 中,因此它们完全存在于 List 上的事实只是一个历史记录。

于 2009-05-28T15:35:17.060 回答
7

首先,ReadOnlyCollection<T>确实实现了IEnumerable<T>and IList<T>。使用 .NET 3.5 和 LINQ 中的所有扩展方法,您可以访问原始List<T>类中几乎所有的查询功能,这是您无论如何都应该使用的ReadOnlyCollection<T>

话虽如此,您最初的问题使我提出了一些建议...

退货List<T>是糟糕的设计,所以它不应该是一个比较点。 List<T>应该用于实现,但对于接口,IList<T>应该返回。框架设计指南特别指出:

不要在公共 API 中使用ArrayList或使用。” List<T>(第 251 页)

如果考虑到这一点,ReadOnlyCollection<T>与 相比绝对没有劣势List<T>。这两个类都实现IEnumerable<T>IList<T>,它们是无论如何都应该返回的接口。

于 2009-05-28T15:45:03.360 回答
3

我不知道为什么最初没有添加它们。但是现在我们有了 LINQ,我当然认为没有理由在未来的语言版本中添加它们。您提到的方法现在可以很容易地写在 LINQ 查询中。这些天来,我几乎对所有事情都使用 LINQ 查询。实际上,我更经常对拥有这些方法感到恼火,List<T>因为它与我编写的扩展方法冲突IEnumerable<T>

于 2009-05-28T15:36:46.840 回答
0

我认为杰夫的答案有点包含您需要的答案;而不是ReadOnlyCollection<T>,返回它的子类...您自己实现的一个子类,以包含您想要使用的方法,而无需升级到 VS2008/LINQ。

于 2009-05-29T02:29:49.690 回答