【问题标题】:Why is IQueryable lacking all the extension methods that IQueryable<T> has?为什么 IQueryable 缺少 IQueryable<T> 拥有的所有扩展方法?
【发布时间】:2013-07-10 19:32:13
【问题描述】:

IEnumerableIEnumerable&lt;T&gt; 相同。是疏忽吗?或者,当您没有指定类型时,是否存在无法实现 .Count().Where() 等扩展的类型?

【问题讨论】:

    标签: c# .net linq iqueryable


    【解决方案1】:

    来自docs

    IQueryable 接口旨在由查询提供程序实现。它只应该由实现IQueryable&lt;T&gt;的提供者实现。如果提供者没有同时实现IQueryable&lt;T&gt;,则不能在提供者的数据源上使用标准查询运算符。

    IEnumerable 是 .NET 没有泛型的时代的产物(当然,我并不是说它已被弃用)。在泛型和IEnumerable&lt;T&gt; 被引入之后,它一直存在于向后兼容。 IQueryable 保持一致以保持一致。基本上,鉴于现在有泛型,并且鉴于其优势,仅在泛型接口上实现这些扩展是有用的。非泛型始终可以使用 Cast&lt;T&gt; 转换为泛型。

    【讨论】:

      【解决方案2】:

      不,这不是疏忽。大多数扩展IQueryable&lt;T&gt;IEnumerable&lt;T&gt; 的方法都需要知道项目的类型。显然,Count()Any() 之类的方法可以在非泛型接口上工作,但它可能会令人困惑。因此,唯一适用于非泛型接口的方法是使它们成为泛型的方法(Cast&lt;T&gt;()OfType&lt;T&gt;())。

      【讨论】:

        【解决方案3】:

        这可能是一个深思熟虑的决定,而不是疏忽,因为 IEnumerable\IQueryable 始终可以使用 Cast 方法转换为 IEnumerable\IQueryable&lt;object&gt;

        这为调用者带来了少量开销,但节省了多次实现许多扩展,例如对于Where,您需要一个通用和非通用版本:

        public static IEnumerable Where(this IEnumerable source, Func<object, bool> predicate) { ... }
        public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) { ... }
        

        【讨论】:

        • 会有一个好处——你不必先打电话给Cast&lt;T&gt; :)
        • @MarcinJuraszek - 这对用户来说是一个小好处,但额外的实施成本并不能证明这么小的开销是合理的。
        • 额外的实施成本是多少?这只是方法声明中的(this IEnueramble&lt;T&gt; source)(this IEnumerable source) 的问题。我很确定这样做还有另一个原因。
        • 不,你不会。因为IEnumerable&lt;T&gt;继承了IEnumerable不需要直接类型知识的方法(例如Count()Any())可以在IEnumerable上实现,其余的(例如Where(pred)Select(func)等)在IEnumerable&lt;T&gt;.
        • @BlueRaja-DannyPflughoeft - 必须有人来实现它们,而对他们来说这样做是有代价的。问题是IEnumerable 上缺少 linq 扩展是否是疏忽。我说这可能是故意的,因为再次为IEnumerable\IQueryable 的非泛型版本实施大多数方法并没有显着的好处。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-06
        • 1970-01-01
        相关资源
        最近更新 更多