【发布时间】:2013-07-10 19:32:13
【问题描述】:
IEnumerable 与 IEnumerable<T> 相同。是疏忽吗?或者,当您没有指定类型时,是否存在无法实现 .Count()、.Where() 等扩展的类型?
【问题讨论】:
标签: c# .net linq iqueryable
IEnumerable 与 IEnumerable<T> 相同。是疏忽吗?或者,当您没有指定类型时,是否存在无法实现 .Count()、.Where() 等扩展的类型?
【问题讨论】:
标签: c# .net linq iqueryable
来自docs:
IQueryable 接口旨在由查询提供程序实现。它只应该由也实现
IQueryable<T>的提供者实现。如果提供者没有同时实现IQueryable<T>,则不能在提供者的数据源上使用标准查询运算符。
IEnumerable 是 .NET 没有泛型的时代的产物(当然,我并不是说它已被弃用)。在泛型和IEnumerable<T> 被引入之后,它一直存在于向后兼容。 IQueryable 保持一致以保持一致。基本上,鉴于现在有泛型,并且鉴于其优势,仅在泛型接口上实现这些扩展是有用的。非泛型始终可以使用 Cast<T> 转换为泛型。
【讨论】:
不,这不是疏忽。大多数扩展IQueryable<T> 和IEnumerable<T> 的方法都需要知道项目的类型。显然,Count() 或 Any() 之类的方法可以在非泛型接口上工作,但它可能会令人困惑。因此,唯一适用于非泛型接口的方法是使它们成为泛型的方法(Cast<T>() 和 OfType<T>())。
【讨论】:
这可能是一个深思熟虑的决定,而不是疏忽,因为 IEnumerable\IQueryable 始终可以使用 Cast 方法转换为 IEnumerable\IQueryable<object>。
这为调用者带来了少量开销,但节省了多次实现许多扩展,例如对于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<T> :)
(this IEnueramble<T> source) 或(this IEnumerable source) 的问题。我很确定这样做还有另一个原因。
IEnumerable<T>继承了IEnumerable不需要直接类型知识的方法(例如Count(),Any())可以在IEnumerable上实现,其余的(例如Where(pred),Select(func)等)在IEnumerable<T>.
IEnumerable 上缺少 linq 扩展是否是疏忽。我说这可能是故意的,因为再次为IEnumerable\IQueryable 的非泛型版本实施大多数方法并没有显着的好处。