【问题标题】:List, IList, IEnumerable, IQueryable, ICollection, which is most flexible return type?List、IList、IEnumerable、IQueryable、ICollection,哪种返回类型最灵活?
【发布时间】:2011-04-03 08:35:35
【问题描述】:

我之前在这里看到过这个问题,但我不满意我了解完整的后果。问题是使用 linq-to-sql 的数据层应该返回什么返回类型,以获得最大的灵活性和查询能力。这是我读过/发现的:

  1. IEnumerable 是有限的,只允许向前读操作。 IEnumerable 是最通用的。我发现 IEnumerable 确实允许查询操作而不是扩展语法。

  2. 由于插入操作,列表允许最大的灵活性。

  3. 应该使用集合而不是列表来启用只读集合。

  4. 永远不应该使用 IQueryable,它应该“使用并关闭”。 IQueryable 不返回列表,而是为数据库生成查询语法。

我觉得我对权衡的感觉更好,但仍然不确定一些事情:

  1. 为什么我要选择接口变体而不是具体类型?即 IList 或 ICollection 与 List 或 Collection。我会得到什么好处?

  2. 我看到扩展操作有效,但扩展查询语法也有效吗?

  3. 之前有人建议我使用 AsQueryable()。但是,如果我没有与数据库的连接,我为什么要这样做呢?看来扩展方法无论如何都可以工作。

【问题讨论】:

  • 从您的问题中删除“列表”类。 IList、IEnumerable、IQueryable 等都是接口,而“List”是一个类。在您的问题中,“列表”类是橘子中的一个苹果。
  • @Stargazer 这是问题的一部分,使用 IList 与 List 有什么好处。我现在正在写一些例子。
  • @Curtis,这就是我要说的:List 实现了 IList,因此 一个 IList。它们是苹果和橙子,我觉得你不明白其中的区别。重新表述涉及两者之间差异的问题的更好方法是,“返回类和返回接口有什么区别?”
  • @Stargazer 我知道接口和类是什么。我知道一个类实现了接口,接口作为契约。我的问题是返回 IList 与 List 的实际区别是什么(或是否存在明显区别)?
  • 不同之处在于 IList 为您提供的功能。 IList 是一个接口,因此它允许您抽象实际返回的内容。如果您的函数返回一个 IList,并且有一天您决定更改该函数的工作方式,那么您可以将其更改为返回 实现 IList 的东西。另一方面,如果您返回一个列表,您将永远受该决定的约束。要更改它,您必须更改任何依赖该函数返回列表的内容。底线:为参数和返回值使用接口。在函数中使用具体类型。

标签: .net linq-to-sql architecture collections


【解决方案1】:

集合对于 DAL 返回通常不是很有用,因为集合不隐式保证顺序。这只是一桶物品。另一方面,IList 确实隐含地保证了顺序。所以我们只能使用 IEnumerable 或 IList。下一个问题是:List 对象是“活的”吗?即,它是否连接到数据支持,以便当您将项目添加到 IList 时,它将反映在数据库中?对于 LINQ-to-SQL,情况并非如此。相反,您应该将实体附加到表中。因此,除非您提供额外的接线,否则列表是多余的。坚持使用 IEnumerable。

【讨论】:

  • @Rex 好的,这是有道理的。你为什么要返回 IList 而不是使用具体的 List?对于有意义的案例有什么好处?
  • @Rex:虽然我同意你的结论,但我建议 DAL 不应该订购收藏品。那属于客户/消费者/业务逻辑。即MyDal.ListCustomers().OrderBy(InvoiceDate).
  • @Curtis 你应该总是返回一个接口,这样你就可以在没有人知道或关心的情况下更改返回对象内部的逻辑。
  • "集合对于 DAL 退货通常不是很有用,因为集合不隐式保证顺序。" - 但您的建议,IEnumerable 也没有。就我个人而言,如果实现可能是延迟评估的,我只会返回 IEnumerable,不太可能是 DAL 结果。返回 IList 保证调用者可以多次枚举结果,并提供 Count 属性。
  • @Joe IEnumerable 并不意味着有序或无序;这取决于实施。但Collection 实际上确实意味着普遍缺乏秩序。
【解决方案2】:

您应该始终返回一个接口而不是具体类型,这是不言而喻的,因为它指定了允许的行为,而不会将使用者绑定到特定的实现。

关于返回哪个接口,你应该考虑方法的目的和调用者的意图。如果您返回一个集合,调用者是否应该能够更改该集合?例如添加/删除项目?如果他们需要做的只是枚举它(做一个 foreach),那么你应该只返回一个 IEnumerable。

【讨论】:

    【解决方案3】:

    1) 最好返回 IList,以便将结果放入任何实现该接口的对象中,而不是强制调用者使用 List。例如,调用者可能希望将结果返回到 ArrayList,如果您将结果返回到 List,这是不可能的。 ArrayList 不是从 List 继承的,但它确实实现了 IList。

    【讨论】:

    • 除了错误之外的好答案。调用者无法控制结果的返回方式。如果我有一个方法“IList GetCustomers()”并且返回的具体类型实际上是“List”,则调用者不能说 ArrayList results = GetCustomers();见stackoverflow.com/questions/539436/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 2015-01-10
    • 2010-11-12
    相关资源
    最近更新 更多