我的问题与这个有关IEnumerable<T>
vs使用的问题有关IReadOnlyCollection<T>
。
我也一直习惯于IEnumerable<T>
将集合公开为返回类型和参数,因为它受益于不可变和延迟执行。
但是,我越来越担心代码中必须枚举参数以避免 ReSharper 给出的可能的多重枚举警告的地方的扩散。我理解为什么 ReSharper 建议这样做,并且我同意它建议的代码(如下)以确保封装(即,不对调用者进行任何假设)。
Foo[] arr = col as Foo[] ?? col.ToArray();
但是,我发现此代码的重复性具有污染性,并且我同意一些IReadOnlyCollection<T>
更好的替代方案,特别是本文中提出的观点,其中指出:
最近一直在考虑回国的利弊
IEnumerable<T>
。从好的方面来说,它几乎与接口一样小,因此它为方法作者提供了比提交更重的替代方案(如
IList<T>
或(天堂禁止)数组)更大的灵活性。但是,正如我在上一篇文章中概述的那样,
IEnumerable<T>
返回会诱使调用者违反Liskov 替换原则。他们太容易使用 LINQ 扩展方法,如Last()
andCount()
,其语义IEnumerable<T>
不承诺。需要一种更好的方法来锁定退回的收藏品,而不会使这种诱惑如此突出。(我想起了巴尼·法夫(Barney Fife)艰难地学习这一课。)
输入
IReadOnlyCollection<T>
.NET 4.5 中的新功能。它只向IEnumerable<T>
:属性添加了一个Count
属性。通过承诺计数,您可以向呼叫者保证您IEnumerable<T>
确实有一个终点站。然后他们可以Last()
问心无愧地使用 LINQ 扩展方法。
然而,细心的人可能已经注意到,本文只讨论了使用IReadOnlyCollection<T>
返回类型。我的问题是,相同的论点是否同样适用于将其用于参数?对此的任何理论想法或评论也将不胜感激。
事实上,我认为使用的一般经验法则是如果使用IReadOnlyCollection<T>
可能存在多个枚举(相对于 ReSharper 警告)IEnumerable<T>
。否则,使用IEnumerable<T>
.