IEnumerable <T>作为返回类型

Val*_*yev 28 c# collections ienumerable enumeration

使用IEnumerable<T>返回类型有问题吗?FxCop抱怨返回List<T>(它建议返回Collection<T>).

好吧,我一直受到一条规则的指导:"尽可能接受,但要回报最大值".

从这个角度来看,返回IEnumerable<T>是一件坏事,但是当我想使用"懒惰检索"时我该怎么办?此外,yield关键字是如此的好.

Jar*_*Par 29

这实际上是一个两部分问题.

1)返回IEnumerable <T>本身有什么问题

一点也不.实际上,如果您使用的是C#迭代器,则这是预期的行为.先发制人地将它转换为List <T>或其他集合类并不是一个好主意.这样做是由调用者对使用模式进行假设.我发现假设调用者的任何事情并不是一个好主意.他们可能有充分的理由为什么他们想要一个IEnumerable <T>.也许他们想将它转换为完全不同的集合层次结构(在这种情况下,浪费了转换为List).

2)在任何情况下,最好还是返回IEnumerable <T>以外的东西吗?

是.虽然假设你的呼叫者并不是一个好主意,但根据你自己的行为做出决定是完全可以的.想象一下这样一个场景,你有一个多线程对象,它将请求排队到一个不断更新的对象中.在这种情况下,返回原始IEnumerable <T>是不负责任的.一旦修改了集合,枚举就会失效并导致执行.相反,您可以拍摄结构的快照并返回该值.以List <T>形式说.在这种情况下,我只是将对象作为直接结构(或接口)返回.

这当然是罕见的情况.


Mar*_*ell 27

不,IEnumerable<T>是一个很好的回到这里,因为你是有希望的是"(类型)值序列"的事情.LINQ等的理想选择,完全可用.

调用者可以很容易地把这个数据到一个列表(或其他) -特别是与LINQ( ,ToList,ToArray等).

这种方法允许您懒惰地回退值,而不是必须缓冲所有数据.绝对是一个好东西.我前几天写了另一个有用的IEnumerable<T>技巧.

  • 如果它提示你考虑你真正*想要返回的内容,fxcop已经完成了它的工作;-p (3认同)

Adr*_*scu 5

IEnumerable 对我来说很好,但它有一些缺点。客户端必须枚举才能得到结果。它无法检查计数等。列表很糟糕,因为你暴露了太多的控制权;客户端可以从中添加/删除等,这可能是一件坏事。收藏似乎是最好的妥协,至少在 FxCop 看来是这样。我总是使用在我的上下文中看起来合适的东西(例如,如果我想返回一个只读集合,我将集合公开为返回类型并返回 List.AsReadOnly() 或 IEnumerable 以通过yield 等进行延迟评估)。具体情况具体分析