What interface should my service return? IQueryable, IList, IEnumerable?
假设我有一个SearchService层,它有一个方法来搜索从某个字符串开始的所有汽车;
1 2 3 4 5 | public static class Searcher{ public IAnInterface<Car> CarsStartingWith(string startWith){ //magic } } |
我的服务应该使用什么接口?iqueryable可以在我的应用程序的其余部分呈现一个良好的流体界面。IEnumerable有一个懒惰的方面。我是最实际的。
为了保持一致性,我希望所有的服务都返回相同的接口,这使得整个过程更加简单。我的回忆也许也是一个选择,但它只提供了那么少的…
我的经验法则如下:
如果我有机会采用例程的核心算法,并以使用yield返回的方式对其进行重构,我将使用IEnumerable
例如,如果我当前的实现在内部使用数组或列表,但我知道,至少在理论上,我可能希望并且能够在内部重新编写它以进行懒惰的评估,那么我将返回IEnumerable。
我发现返回IEnumerable的收益绝对值得使用它。
但是,如果算法本身需要在返回之前对结果进行全面评估(很少,但确实会发生),那么我将使用ilist。基本上,如果我已经在计算它,我会返回它。IList实现了IEnumerable,因此所有与LINQ相关的用例都仍然可以工作,但是您会失去延迟的评估。如果我已经被迫提前评估了,那不是问题。
我很少回宜家。我唯一一次使用这个接口是直接创建一个可查询的数据访问层,或者类似的东西。在大多数情况下,使用这种方法的开销不值得获得收益。
但是,如果您的目标是始终使用单个接口(我不一定同意此目标),我将坚持IEnumerable
我会选择
除非你有严重的理由不这么做,否则一定要和
其余的,
如果您希望所有的服务返回相同的接口,那么我可能会选择
如果需要,您的呼叫者可以很容易地转换为
1 2 3 | IEnumerable<Car> cars = Searcher.CarsStartingWith("L"); var carsList = cars.ToList(); var queryableCars = cars.AsQueryable(); |
简短回答:视情况而定。
更长的回答:返回客户端代码需要的最丰富的类型。在大多数情况下,如果您不需要延迟加载,IList可以工作。仍然可以使用LINQ查询IList或IEnumerable。如果需要延迟加载,则使用IEnumerable或IQueryable。
附带说明:为所有服务返回相同的接口似乎是一个高尚的目标,但是考虑到不同的客户机使用模式,您可能希望返回不同的接口。
通常对我来说,在
如果您使用IQueryable作为返回类型,那么您有一个带有泄漏抽象的服务层。