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

时间:2009-03-25 14:55:08

标签: c# .net

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

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

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

我希望我的所有服务都返回相同的界面以保持一致性,使整个事情变得更容易 ICollection可能也是一个选项,但它提供的东西很少......

7 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

我的经验法则如下:

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

例如,如果我当前的实现使用数组或List&lt; T&gt;在内部,但我知道,至少在理论上,我可能想要并且能够在内部重新进行懒惰评估,我将返回一个IEnumerable&lt; T&gt;。

我发现返回IEnumerable&lt; T&gt;的收益绝对值得使用它的麻烦。

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

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

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

简短回答:这取决于。

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

附注:为所有服务返回相同的界面似乎是一个崇高的目标,但考虑到不同的客户端使用模式,您可能希望返回不同的界面。

答案 4 :(得分:2)

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

如果需要,您的来电者可以轻松转换为IQueryable或创建List

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

答案 5 :(得分:2)

除非您有充分理由不这样做,否则请始终使用IEnumerable。然后,您可以使用yield return实现getter。

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

其余的,IEnumerable与其他人之间存在重大差异:它是只读的。

答案 6 :(得分:0)

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