为什么Enumerable.Except可以在C#中的字符串数组上使用?

时间:2011-02-20 13:31:11

标签: c# linq extension-methods

示例

以下是我在Pete on Software博客中找到的代码示例:

var listThree = new string[] { "Pete", "On", "Software" };  
var listFour = new string[] { "Joel", "On", "Software" };  
stringExcept = listThree.Except(listFour);

代码编译并运行。到目前为止一切都很好。

问题

但是,我不明白为什么会这样。

那么,任何人都可以解释为什么我可以在字符串数组上使用Enumerable.Except吗?

也许,如果有人能够解释如何阅读Enumerable.Except的签名并给我一个代码示例,我会很清楚:

public static IEnumerable<TSource> Except<TSource>(
    this IEnumerable<TSource> first,
    IEnumerable<TSource> second
)

我所知道的

我知道泛型和扩展方法的概念。但显然不足以理解上面的代码示例。我也已经使用了一些基本的Linq查询。

5 个答案:

答案 0 :(得分:4)

Except是一种扩展方法,它扩展了实现IEnumerable<T>的任何类型。这包括实现IEnumerable<T>的{​​{3}}类型。

链接页面上的说明解释了为什么文档未显示System.Array实施IEnumerable<T>

  

在.NET Framework 2.0版中,Array类实现System.Collections.Generic.IList<T>System.Collections.Generic.ICollection<T>System.Collections.Generic.IEnumerable<T>通用接口。这些实现在运行时提供给数组,因此文档构建工具不可见。因此,通用接口不会出现在Array类的声明语法中,并且没有可通过将数组转换为通用接口类型(显式接口实现)来访问的接口成员的参考主题。将数组转换为其中一个接口时要注意的关键是添加,插入或删除元素的成员抛出NotSupportedException

答案 1 :(得分:2)

它只是说如果你在这种情况IEnumerable中有TSource给定类型string,你可以使用相同类型的另一个IEnumerable除外它返回相同类型的第三个IEnumerable。关键是两个IEnumerable输入必须相同(显然返回的类型相同)。

答案 2 :(得分:2)

T的数组(或者说T[])也是IEnumerable<T>。在您的问题中,T为System.StringEnumerable.ExceptIEnumerable<T>上的扩展方法,因此它也适用于string[]stringExcept = listThree.Except(listFour);等于

stringExcept = Enumerable.Except(listThree, listFour).

答案 3 :(得分:1)

编译器将TSource参数与string匹配,因为字符串数组实现IEnumerable<string>接口,因此匹配扩展方法的第一个参数。所以答案是两件事:

  • string[]实施IEnumerable<string>
  • 编译器足够智能,可以推断出通用参数

答案 4 :(得分:0)

Except方法返回第一个可枚举中的元素,这些元素也不会出现在 第二个可枚举。因此,在您指定的情况下,结果将是{"Pete", "Joel"}

在这种情况下,考虑字符串数组可能是一个红色的鲱鱼。从对象平等(http://msdn.microsoft.com/en-us/library/system.object.equals.aspx)

的角度思考可能更有利

Microsoft文档位于:http://msdn.microsoft.com/en-us/library/system.linq.enumerable.except.aspx