【发布时间】:2017-05-06 23:07:02
【问题描述】:
我的问题与this one 有关IEnumerable<T> 与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>不承诺。需要一种更好的方法来锁定返回的集合 没有使这种诱惑如此突出。 (我想起了巴尼 法夫艰难地学习了这一课。)
输入
IReadOnlyCollection<T>,.NET 4.5 中的新功能。它只增加了一个IEnumerable<T>的属性:Count属性。通过承诺计数, 您向来电者保证您的IEnumerable<T>确实有 终点站。然后他们可以使用 LINQ 扩展方法,例如Last()无愧于心。
但是,细心的人可能已经注意到,本文只讨论了使用IReadOnlyCollection<T> 来表示返回类型。我的问题是,相同的论点是否同样适用于将其用于参数?对此的任何理论思想或方法也将不胜感激。
事实上,如果使用IEnumerable<T>,我认为使用IReadOnlyCollection<T> 的一般经验法则是可能存在多个枚举(相对于ReSharper 警告)。否则,使用IEnumerable<T>。
【问题讨论】:
-
resharper 的注释中有一个名为
[NoEnumeration]的属性,它只是一个属性,但那里说Indicates that IEnumerable, passed as parameter, is not enumerated.它什么也没做,但我用它是因为它很酷 -
@M.kazemAkhgary,这很酷,而且很有用,我猜你没有枚举
IEnumerable。但我的问题比那个用例更广泛,更多的是关于IEnumerable枚举的位置。在这些情况下,IReadOnlyCollection<T>是更好的选择吗,出于我提到的原因(即文章中提出的观点)?
标签: c# resharper .net-4.5 ienumerable readonly-collection