根据 FxCop 的建议和我个人的倾向,我一直鼓励我所指导的团队尽可能多地使用 ReadOnlyCollections。 如果只是为了让列表的收件人无法修改其内容就好了。 在他们的理论中,这是面包和面包。 黄油。 问题是 List<> 接口更加丰富,公开了各种有用的方法。 他们为什么做出这样的选择?
您是否只是放弃并返回可写集合? 您是否返回只读集合,然后将它们包装在可写集合中? 啊啊啊。
更新:
谢谢,我熟悉框架设计指南,这就是团队使用 FxCop 来强制执行它的原因。 然而,这个团队正在使用 VS 2005(我知道,我知道),因此告诉他们 LINQ/扩展方法可以解决他们的问题只会让他们感到难过。
他们了解到,List.FindAll() 和 .FindFirst() 比编写 foreach 循环更清晰。 现在我敦促他们使用 ReadOnlyCollections,但他们失去了清晰度。
也许还有一个我没有发现的更深层次的设计问题。
-- 抱歉,原来的帖子应该提到 VS2005 的限制。 我已经生活了这么久,我只是没有注意到。
Following the suggestions of FxCop and my personal inclination I've been encouraging the team I'm coaching to use ReadOnlyCollections as much possible. If only so that recipients of the lists can't modify their content. In their theory this is bread & butter. The problem is that the List<> interface is much richer exposing all sorts of useful methods. Why did they make that choice?
Do you just give up and return writable collections? Do you return readonly collections and then wrap them in the writable variety? Ahhhhh.
Update:
Thanks I'm familiar with the Framework Design Guideline and thats why the team is using FxCop to enforce it. However this team is living with VS 2005 (I know, I know) and so telling them that LINQ/Extension methods would solve their problems just makes them sad.
They've learned that List.FindAll() and .FindFirst() provide greater clarity than writing a foreach loop. Now I'm pushing them to use ReadOnlyCollections they lose that clarity.
Maybe there is a deeper design problem that I'm not spotting.
-- Sorry the original post should have mentioned the VS2005 restriction. I've lived with for so long that I just don't notice.
发布评论
评论(4)
.NET Framework 设计指南第二版第 8.3.2 节:
我们使用 ReadOnlyCollections 来表达我们返回集合的意图。
为了方便起见,您提到的
List
方法已添加到 .NET 2.0 中。 在 C# 3.0 / .NET 3.5 中,您可以使用扩展方法(并使用 LINQ 运算符)在ReadOnlyCollection
(或任何IEnumerable
)上重新获取所有这些方法也),所以我认为没有任何动机将它们本地添加到其他类型。 它们存在于 List 上的事实只是一个历史记录,因为现在存在可用的扩展方法,但在 2.0 中不存在。Section 8.3.2 of the .NET Framework Design Guidelines Second Edition:
We go with ReadOnlyCollections to express our intent of the collection returned.
The
List<T>
methods you speak of were added in .NET 2.0 for convenience. In C# 3.0 / .NET 3.5, you can get all those methods back onReadOnlyCollection<T>
(or anyIEnumerable<T>
) using extension methods (and use LINQ operators as well), so I don't think there's any motivation for adding them natively to other types. The fact that they exist at all on List is just a historical note due to the presence of extension methods being available now but weren't in 2.0.首先,
ReadOnlyCollection
确实实现了IEnumerable
和IList
。 借助 .NET 3.5 和 LINQ 中的所有扩展方法,您可以访问原始List
类在查询方面的几乎所有功能,这就是您应该使用无论如何,ReadOnlyCollection
。话虽这么说,你最初的问题让我提出一些建议......
返回
List
是糟糕的设计,所以它不应该成为比较点。 实现时应使用List
,但对于接口,应返回IList
。 框架设计指南特别指出:“请勿在公共 API 中使用
ArrayList
或List
。” (第 251 页)如果考虑到这一点,与
List
相比,ReadOnlyCollection
绝对没有劣势。 这两个类都实现了IEnumerable
和IList
,它们是无论如何都应该返回的接口。First off,
ReadOnlyCollection<T>
does implementIEnumerable<T>
andIList<T>
. With all of the extension methods in .NET 3.5 and LINQ, you have access to nearly all of the functionality from the originalList<T>
class in terms of querying, which is all you should do with aReadOnlyCollection<T>
anyways.That being said, your initial question leads me to make some suggestions...
Returning
List<T>
is bad design, so it shouldn't be a point of comparison.List<T>
should be used for implementation, but for the interface,IList<T>
should be returned. The Framework Design Guidelines specifically state:"DO NOT use
ArrayList
orList<T>
in public APIs." (Page 251)If you take that into consideration, there is absolutely no disadvantage to
ReadOnlyCollection<T>
when compared toList<T>
. Both of these classes implementIEnumerable<T>
andIList<T>
, which are the interfaces that should be returned anyways.我不知道为什么最初没有添加它们。 但现在我们有了 LINQ,我当然认为没有理由在该语言的未来版本中添加它们。 您提到的方法现在可以轻松地编写在 LINQ 查询中。 如今,我几乎所有事情都使用 LINQ 查询。 实际上,我更经常对
List
具有这些方法感到恼火,因为它与我针对IEnumerable
编写的扩展方法冲突。I don't have any insight as to why they weren't originally added. But now that we have LINQ I certainly see no reason to add them in future versions of the language. The methods you mentioned can easily be written in a LINQ query today. These days I just use the LINQ queries for pretty much everything. I actually more often get annoyed with
List<T>
having those methods because it conflicts with extension methods I write againstIEnumerable<T>
.我认为杰夫的回答有点包含你需要的答案; 而不是
ReadOnlyCollection
,返回它的一个子类...您自己实现的一个子类,以包含您想要使用的方法,而无需升级到 VS2008/LINQ。I think Jeff's answer kinda contains the answer you need; instead of
ReadOnlyCollection<T>
, return a subclass of it... one that you implement yourself to include the methods that you'd like to use without upgrading to VS2008/LINQ.