我的问题与this one有关IEnumerable<T>
vs IReadOnlyCollection<T>
的使用有关。
我也总是使用IEnumerable<T>
将集合作为返回类型和参数公开,因为它既可以不可变又可以延迟执行。
但是,我越来越关注代码中地点的增加,我必须枚举一个参数,以避免ReSharper给出的可能的多个枚举警告。我理解为什么ReSharper建议这一点,我同意它建议的代码(下面)以确保封装(即,没有关于调用者的假设)。
Foo[] arr = col as Foo[] ?? col.ToArray();
但是,我发现此代码的重复性是污染性的,并且我同意某些来源IReadOnlyCollection<T>
是更好的选择,尤其是this article中提出的要点,其中指出:
最近,我一直在考虑回归的优点和缺点
IEnumerable<T>
。从好的方面来说,它与接口一样小,所以它 让你作为方法作者比提交更灵活 较重的替代方案,如
IList<T>
或(heaven forbid)数组。但是,正如我在the last post中所述,
IEnumerable<T>
返回 诱使来电者违反Liskov Substitution Principle。它太 他们很容易使用Last()
和Count()
等LINQ扩展方法, 其语义IEnumerable<T>
不承诺。需要更好的方法来锁定返回的集合 没有让这种诱惑如此突出。 (我想起了巴尼 Fife努力学习这一课。)
在.NET 4.5中输入新的
IReadOnlyCollection<T>
。它只增加了一个 属性IEnumerable<T>
:Count
属性。通过承诺计数, 你保证你的呼叫者你的IEnumerable<T>
确实有一个 总站。然后,他们可以使用像Last()
这样的LINQ扩展方法 清醒的良心。
但是,正如观察者可能已经注意到的那样,本文仅讨论如何使用IReadOnlyCollection<T>
作为返回类型。我的问题是,相同的论点同样适用于将其用于参数吗?任何关于此的理论思考或评论也将受到赞赏。
事实上,我认为使用IReadOnlyCollection<T>
的一般经验法则是,如果使用IEnumerable<T>
,可能会有多次枚举(相对于ReSharper警告)。否则,请使用IEnumerable<T>
。
答案 0 :(得分:5)
在进一步考虑之后,我得出结论,根据我在我的问题中提到的文章,确实可以使用IReadOnlyCollection<T>
作为参数,但仅限于它肯定会有的功能列举一下。如果枚举是基于其他参数,对象状态或工作流的条件,那么它仍然应该作为IEnumerable<T>
传递,以便在语义上确保延迟评估。