我的服务应该返回什么界面? IQueryable,IList,IEnumerable?

想象一下,我有一个SearchService层,它有一个方法来搜索以某个字符串开头的所有汽车;

public static class Searcher{ public IAnInterface CarsStartingWith(string startWith){ //magic } } 

我的服务应该使用什么界面?
IQueryable可以在我的应用程序的其余部分呈现一个漂亮的流体界面。
IEnumerable有一个懒惰的方面。
IList是最实用的。

我想让我的所有服务返回相同的界面以保持一致性,使整个事情变得更加容易。
ICollection可能也是一个选项,但它只提供这么少……

如果您希望所有服务都返回相同的接口,那么我可能会选择IEnumerable<>

如果需要,调用者可以很容易地转换为IQueryable或创建List

 IEnumerable cars = Searcher.CarsStartingWith("L"); var carsList = cars.ToList(); var queryableCars = cars.AsQueryable(); 

我会选择IEnumerable因为它在框架中有一个更重要的位置,为需要它的人提供多function性,同时也为那些尚未陷入LINQ之类的人提供熟悉。

我的经验法则如下:

如果我有可能采用例程的核心算法并以我可以使用yield return的方式重构它,我将使用IEnumerable

例如,如果我当前的实现在内部使用数组或List ,但我知道,至少在理论上,我可能希望并且能够在内部重新编写它以进行延迟评估,我将返回一个IEnumerable < T>。

我发现返回IEnumerable 的收益绝对值得使用它的麻烦。

但是,如果算法本质上需要在返回之前完全评估结果(很少见,但确实发生),我将使用IList 。 基本上,如果我已经计算了它,我会把它还给它。 IList 实现了IEnumerable ,因此所有与LINQ相关的用例仍然有效,但是你失去了懒惰的评估。 如果我已经被迫提前评估,那不是问题。

我很少回归IQueryable。 我唯一一次使用这个界面就是我直接创建一个可查询的数据访问层,或类似的东西。 在大多数情况下,使用它的开销不值得。

但是,如果你的目标是始终使用单个界面(我不一定同意这个目标),我会坚持使用IEnumerable

IQueryable对它的要求相当高 – 例如,你不能返回一个数组。

通常对我来说, IEnumerableIList之间的选择通常最终会在标准情况下更容易实现。

简答:这取决于。

更长的答案:返回客户端代码所需的最丰富的类型。 如果您不需要延迟加载,IList在大多数情况下都可以工作。 您仍然可以使用Linq查询IList或IEnumerable。 如果需要延迟加载,则使用IEnumerable或IQueryable。

旁注:为所有服务返回相同的界面可能看起来像一个崇高的目标,但考虑到不同的客户端使用模式,您可能希望返回不同的接口。

总是使用IEnumerable除非你有充分的理由不这样做。 然后,您可以使用yield return实现getter。

IQueryable是一个完全不同的鱼。 作为典型的内存容器的替代品,并不是随便实现的。

其余的, IEnumerable和其他人之间有一个很大的不同:它是readonly。

如果您使用IQueryable作为返回类型,则您有一个具有漏洞抽象的服务层。