使用IReadOnlyCollection< T>代替IEnumerable< T>用于参数以避免可能的多重枚举 [英] Using IReadOnlyCollection<T> instead of IEnumerable<T> for parameters to avoid possible multiple enumeration

查看:101
本文介绍了使用IReadOnlyCollection< T>代替IEnumerable< T>用于参数以避免可能的多重枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与有关使用 IEnumerable< T> IReadOnlyCollection< T>

My question is related to this one concerning the use of IEnumerable<T> vs IReadOnlyCollection<T>.

我也一直使用 IEnumerable< T> 将集合公开为返回类型和参数,因为它既受益于不变性又懒惰地执行。

I too have always used IEnumerable<T> to expose collections as both return types and parameters because it benefits from being both immutable and lazily executed.

我越来越担心代码中必须枚举参数的地方的泛滥,以避免ReSharper发出可能的多重枚举警告。我理解为什么ReSharper建议这样做,并且我同意下面建议的代码以确保封装(即,不假设调用方)。

However, I am becoming increasingly concerned about the proliferation of places in my code where I must enumerate a parameter to avoid the possible multiple enumeration warning that ReSharper gives. I understand why ReSharper suggests this, and I agree with the code it suggests (below) in order to ensure encapsulation (i.e., no assumptions about the caller).

 Foo[] arr = col as Foo[] ?? col.ToArray();

但是,我发现此代码具有重复性,并且我同意一些 IReadOnlyCollection< T> 是更好的选择,尤其是本文,其中指出:

However, I find the repetitiveness of this code pollutive, and I agree with some sources that IReadOnlyCollection<T> is a better alternative, particularly the points made in this article, which states:

最近,我一直在考虑返回
IEnumerable< T> 的优缺点。

Lately, I’ve been considering the merits and demerits of returning IEnumerable<T>.

从好的方面来说,它与接口获得的最小作用相同,因此与承诺使用
较重的替代方法(例如<$)相比,
为方法作者提供了更大的灵活性。 c $ c> IList< T>
或(天堂禁止)一个数组。

On the plus side, it is about as minimal as an interface gets, so it leaves you as method author more flexibility than committing to a heavier alternative like IList<T> or (heaven forbid) an array.

但是,正如我在最后一篇帖子 IEnumerable< T> 返回
诱使调用者违反 Liskov替代原则。对于他们来说,使用$ Last() Count()
的语义 IEnumerable< T> 不能保证。

However, as I outlined in the last post, an IEnumerable<T> return entices callers to violate the Liskov Substitution Principle. It’s too easy for them to use LINQ extension methods like Last() and Count(), whose semantics IEnumerable<T> does not promise.

需要一种更好的锁定方法返回的收藏集
却没有引起如此大的诱惑。 (让我想起了Barney
Fife艰难地学习本课。)

What’s needed is a better way to lock down a returned collection without making such temptations so prominent. (I am reminded of Barney Fife learning this lesson the hard way.)

输入 IReadOnlyCollection< T> ,.NET 4.5中的新功能。它将仅一个
属性添加到 IEnumerable< T> Count 属性。通过承诺
,您可以确保呼叫方您的 IEnumerable< T> 确实具有
终点。然后,他们可以使用带有 Last()之类的LINQ扩展方法。

Enter IReadOnlyCollection<T>, new in .NET 4.5. It adds just one property to IEnumerable<T>: the Count property. By promising a count, you assure your callers that your IEnumerable<T> really does have a terminus. They can then use LINQ extension methods like Last() with a clear conscience.

但是,正如观察者可能注意到的那样,本文仅讨论将 IReadOnlyCollection< T> 用于返回类型。我的问题是,同样的论点同样适用于将其用于参数吗?

However, as the observant may have noticed, this article only talks about using IReadOnlyCollection<T> for return types. My question is, would the same arguments equally apply to using it for parameters also? Any theoretical thoughts or comments on this would also be appreciated.

事实上,我在考虑使用 IReadOnlyCollection< T>的一般经验法则。 ; 如果使用 IEnumerable< T> ,则可能会有多个枚举(相对于ReSharper警告)。否则,请使用 IEnumerable< T>

In fact, I'm thinking a general rule of thumb to use IReadOnlyCollection<T> would be where there would be possible multiple enumeration (vis-à-vis the ReSharper warning) if IEnumerable<T> is used. Otherwise, use IEnumerable<T>.

推荐答案

对此有所考虑此外,根据我在问题中提到的文章,我得出的结论是,使用 IReadOnlyCollection< T> 作为参数确实可以,但仅在肯定会列举的功能。如果枚举是基于其他参数,对象状态或工作流的条件,则仍应将其作为 IEnumerable< T> 传递,以便从语义上确保惰性评估。

Having thought about this further, I have come to the conclusion, based on the article I mentioned in my Question, that it is indeed OK to use IReadOnlyCollection<T> as a parameter, but only in functions where it will definitely be enumerated. If enumeration is conditional based on other parameters, object state, or workflow, then it should still be passed in as IEnumerable<T> so that lazy evaluation is semantically ensured.

这篇关于使用IReadOnlyCollection&lt; T&gt;代替IEnumerable&lt; T&gt;用于参数以避免可能的多重枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆