使用 IReadOnlyCollection<T>而不是 IEnumerable&lt;T&gt;用于避免可能的多次枚举的参数 [英] Using IReadOnlyCollection&lt;T&gt; instead of IEnumerable&lt;T&gt; for parameters to avoid possible multiple enumeration

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

问题描述

我的问题与这个有关,关于IEnumerable vsIReadOnlyCollection.

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

我也一直使用 IEnumerable 将集合公开为返回类型和参数,因为它受益于不可变和延迟执行.

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 是更好的替代方案,尤其是 这篇文章,其中说明:

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.

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

从好的方面来说,它和界面一样小,所以它让你作为方法作者比承诺一个更灵活更重的替代方案,如 IList 或 (天堂禁止) 一个数组.

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返回引诱调用者违反 Liskov 替换原则.它太便于他们使用 Last()Count() 等 LINQ 扩展方法,其语义 IEnumerable 不保证.

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.

需要一种更好的方法来锁定返回的集合没有使这种诱惑如此突出.(我想起了巴尼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,.NET 4.5 中的新功能.它只添加了一个IEnumerable 的属性:Count 属性.通过承诺计数,你向你的呼叫者保证你的 IEnumerable 确实有终点站.然后他们可以使用像 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 作为返回类型.我的问题是,同样的论点是否同样适用于将它用于参数?对此的任何理论想法或评论也将不胜感激.

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 的一般经验法则,如果 >IEnumerable 被使用.否则,使用 IEnumerable.

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 作为参数,但仅限于肯定会枚举的函数中.如果枚举是基于其他参数、对象状态或工作流的条件,则仍应将其作为 IEnumerable 传入,以便在语义上确保延迟评估.

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<T>而不是 IEnumerable&lt;T&gt;用于避免可能的多次枚举的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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