List, IList, IEnumerable, IQueryable, ICollection, which is most flexible return type?
我以前在这里看到过这个问题,但我不满意我理解完整的后果。问题是,使用LINQ to SQL返回的数据层应该返回什么类型,以获得最大的灵活性和查询能力。这是我读到/找到的:
IEnumerable是有限的,只允许进行前读操作。IEnumerable是最通用的。我发现IEnumerable允许查询操作和扩展语法。
由于插入操作,list允许最大的灵活性。
应使用集合而不是列表来启用只读集合。
iqueryable不应该被使用,它应该被"使用并关闭"。iqueryable不返回列表,但为数据库生成查询语法。
我觉得我对权衡有更好的感觉,但对一些事情仍不确定:
为什么我要选择接口变体而不是具体类型?即iList或iCollection与List或Collection。我能得到什么好处?
我看到扩展操作可以工作,但是扩展查询语法也可以工作吗?
有人建议我以前使用asqueryable()。但是,如果我没有与数据库的连接,为什么要这样做?似乎扩展方法无论如何都有效。
- 从问题中删除"list"类。IList、IEnumerable、IQueryable等都是接口,而"List"是类。"单子"课是你问题中橙子之间的一个苹果。
- @Stargazer是问题的一部分,使用IList和List有什么好处。我现在正在写一些例子。
- @柯蒂斯,我是这么说的:list实现了ilist,因此是ilist。它们是苹果和桔子,我觉得你不明白它们的区别。一个更好的方法是重新表述一个涉及两者之间差异的问题,"返回类和返回接口之间的区别是什么?"
- @Stargazer我知道接口是什么,类是什么。我知道类实现了接口,接口作为契约。我的问题是返回ilistvs list的有形差异(或是否存在有形差异)是什么?
- @如果没有明显的区别,那么如何理性地选择最佳选择呢?
- 区别在于IList提供给您的功能。IList是一个接口,因此它允许您抽象实际返回的内容。如果函数返回一个IList,并且有一天您决定更改函数的工作方式,那么您可以将其更改为返回实现IList的内容。另一方面,如果您返回一个列表,那么您将永久地受到该决定的约束。要更改它,您必须更改依赖该函数返回列表的任何内容。底线:对参数和返回值使用接口。在函数中使用具体类型。
- 我会说从那个列表中删除iqueryable,它完全是一个不同的野兽。
对于DAL返回,集合通常不是很有用,因为集合不能隐式地保证顺序。只是一桶东西。另一方面,一个伊利斯特人却暗中保证了秩序。因此,我们只能选择IEnumerable或IList。下一个问题是:列表对象是"活动"的吗?也就是说,它是否连接到数据备份,以便在向IList添加项时,它将反映在数据库中?对于Linq to SQL,情况并非如此。相反,您应该将实体附加到表中。所以,除非你提供额外的线路,否则列表是多余的。坚持IEnumerable。
- @雷克斯,好吧,这是有道理的。为什么你要用具体的列表返回ilist?它对那些有意义的案例有什么好处?
- @雷克斯:虽然我同意你的结论,但尊敬的是,我建议DAL不应该订购收藏品。它属于客户机/消费者/业务逻辑。即MyDal.ListCustomers().OrderBy(InvoiceDate)。
- @P.坎贝尔,我会关心这次行动的速度,特别是在不需要的时候。
- @Curtis您应该始终返回一个接口,这样您就可以在不需要任何人知道或关心的情况下更改返回对象内部的逻辑。
- @Rex您可以在不需要任何人知道或关心的情况下更改返回对象内部的逻辑,这就是封装的要点。0;
- @REX接口的真正目的是允许类型变化,而不是对象提供的封装。类型差异也可以通过从一个公共基类继承来解决,但接口可能因为单个继承而成为.NET中的首选。
- @柯蒂斯,我们说的是同样的话。如果实现隐藏在接口后面,它可能是任何东西。而且,永远不要从列表继承。它会引起头痛。
- "对于DAL返回,集合通常不是很有用,因为集合不能隐式地保证顺序。"—但是,您的建议IEnumerable也不能。就我个人而言,我只会返回IEnumerable,如果实现可能被懒惰地评估,就不太可能得到DAL结果。返回ilist保证调用方可以多次枚举结果,并提供count属性。
- @JoeIEnumerable并不意味着命令或缺少命令;这取决于实现。但事实上,Collection的确暗示了普遍缺乏秩序。
您应该始终返回一个接口,而不是具体的类型,这是不言而喻的,因为它指定了允许的行为,而不将使用者与特定的实现联系起来。
对于要返回的接口,您应该考虑方法的目的和调用者的意图。如果返回集合,调用方是否能够更改集合?例如,添加/删除项目?如果他们只需要枚举它(执行foreach),那么您应该返回一个IEnumerable。
1)最好返回一个IList,这样结果就可以放入实现该接口的任何对象中,而不是强制调用者使用列表。例如,调用方可能希望将结果返回到ArrayList,如果将结果返回到列表中,则不可能这样做。arraylist不从列表继承,但它实现了ilist。
- 回答正确,但错误除外。调用方无法控制返回结果的方式。如果我有一个方法"i list getcustomers()",并且返回的具体类型实际上是"list",调用方就不能说arraylist results=getcustomers();请参见stackoverflow.com/questions/539436/…