为什么Enumerable不继承自IEnumerable <t> </t>

时间:2010-06-09 08:56:53

标签: c# linq ienumerable enumerable

我对这个问题非常困惑,无法理解。在Enumerable文档中,我读到了这个:

  

实现System.Collections.Generic.IEnumerable

以及Select()之类的一些方法返回IEnumerable<TSource>,我们可以在使用它之后使用Where()之类的其他方法。例如:

names.Select(name => name).Where(name => name.Length > 3 );

Enumerable不会继承IEnumerable<T>,而IEnumerable<T>也不会包含Select()Where()等......

我错了吗? 或者有什么理由吗?

6 个答案:

答案 0 :(得分:8)

Select(),Where()等是“extension methods”。它们需要在“其他地方”定义,因为接口不能提供方法的实现。

您可以通过参数列表中的关键字“this”识别扩展方法。例如:

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate
)

可以用作IEnumerable<TSource>上带有一个参数Func<TSource, bool> predicate的方法。

答案 1 :(得分:0)

正确。但这句话呢?

  

实现System.Collections.Generic.IEnumerable

根据这句话,我们必须在IEnumerable<T>接口中定义方法,并通过继承在Enumerable类中实现。它是否正确?

为什么首选的扩展方法可以继承?

答案 2 :(得分:0)

IEnumerable出现在IEnumerable<T>之前,这是一个2.0+接口。

答案 3 :(得分:0)

&#34;为什么首选的扩展方法反对继承?&#34;

Enumerable是一个静态类,它为IEnumerable实现了50多种扩展方法。这使您可以在实现IEnumerable的类型上使用所有这些扩展方法,而不必强制程序员为每个集合类型实现所有这些方法。如果Enumerable是一个接口而不是一个静态类,那么每个集合类型(如List,Dictionary,Set等)都有自己的扩展方法实现。

答案 4 :(得分:0)

解决此问题的方法是使用Cast<T>()方法将元素转换为相同的类型,该方法返回相同元素的IEnumerable<T>版本。

DataTable dt = ...
dt.Rows.Cast<DataRow>().Where()...

Rows的类型为IEnumerable,在转换后,它变为IEnumerable<DataRow>类型,LINQ扩展方法支持该类型。

答案 5 :(得分:-2)

我曾说过,你也可以阅读Jon Skeet的这篇文章Iterators, iterator blocks and data pipelines以获得进一步的见解