我读了很多关于为什么返回IEnumerable而不是IList(或类似的东西)更好的原因。但现在我陷入了困境。
考虑这样的事情:我有一些函数可以执行多个枚举,因此将IReadOnlyCollection作为参数,创建一个新的List并将其作为IEnumerable返回。
IEnumerable<int> Foo1(IReadOnlyCollection<int> bar)
{
bar.Any();
bar.First();
return new List<int>() {1, 2, 3};
}
IEnumerable<int> Foo2(IReadOnlyCollection<int> bar)
{
bar.Any();
bar.First();
return new List<int>() {1, 2, 3};
}
IEnumerable Foo3 ...
现在,如果我想一个接一个地打电话给我,我必须做这样的事情
var tmp = Foo1(new List<int>() {1, 2, 3});
tmp = Foo2(tmp.ToList());
tmp = Foo3(tmp.ToList());
tmp = Foo4(tmp.ToList());
tmp = Foo5(tmp.ToList());
这意味着我必须创建一个11个列表。第一个,每个函数一个,每个函数调用一个。但事实上,创建6个列表就足够了。 有没有更好的方法,或者在返回IEnumerable时这只是一个可能的缺点?
答案 0 :(得分:2)
一般来说,这只是返回IEnumerable时固有的权衡。
返回IEnumerable的优点是你可以改变你的Foo()实现来返回几乎任何类型的集合(甚至是带有yield return或LINQ的惰性序列),而无需更改API。在创建界面时,平衡这一优势非常重要,因为IEnumerable API的消费者想要多次枚举它总是必须将其转换为集合。
更一般地说,返回更具体的类型(例如List over IList)对消费者最有用,而且在维护API方面最具挑战性。有些事情需要考虑:
如果您只是担心创建新列表的性能(几乎在所有情况下都不应该成为真正的问题),您可以随时创建扩展名:
public static IReadOnlyCollection<T> AsReadOnlyCollection<T>(this IEnumerable<T> @this)
{
return @this as IReadOnlyCollection<T> ?? @this.ToArray();
}