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

为什么可以在C#中的字符串数组上使用Enumerable.Except?,c#,linq,extension-methods,C#,Linq,Extension Methods,示例 下面是我在博客上找到的一个代码示例: 代码编译并运行。到目前为止还不错 问题 然而,我不明白为什么它会起作用 那么,有人能解释为什么我可以在字符串数组上使用吗 也许,如果有人能解释如何读取可枚举的签名,我会很清楚。除了之外,请给我一个代码示例: public static IEnumerable<TSource> Except<TSource>( this IEnumerable<TSource> first, IEnumerable&l

示例

下面是我在博客上找到的一个代码示例:

代码编译并运行。到目前为止还不错

问题

然而,我不明白为什么它会起作用

那么,有人能解释为什么我可以在字符串数组上使用吗

也许,如果有人能解释如何读取
可枚举的签名,我会很清楚。除了
之外,请给我一个代码示例:

public static IEnumerable<TSource> Except<TSource>(
    this IEnumerable<TSource> first,
    IEnumerable<TSource> second
)
公共静态IEnumerable除外(
这是第一次,
数秒
)
我所知道的


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

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

  • string[]
    实现
    IEnumerable
  • 编译器足够智能,可以推断泛型参数

它只是说,如果您有一个给定类型的
IEnumerable
TSource
,在这种情况下
字符串
,您可以将它与另一个相同类型的
IEnumerable
进行比较,然后获得第三个相同类型的
IEnumerable
。关键的一点是,两个
IEnumerable
输入必须相同(显然返回的类型相同)。

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

在这种情况下,从字符串数组的角度考虑可能是一种误导。从对象相等的角度考虑可能更有利(

Microsoft文档在这里:

一个T数组(或者说a
T[]
),也是一个
IEnumerable
。在你的问题中,T是
System.String
。和
可枚举。除了
IEnumerable
的扩展方法,所以它也适用于
字符串[]
stringExcept=listThree.Except(listFour);
等于

stringExcept = Enumerable.Except(listThree, listFour).

Except
是一种扩展方法,它扩展了实现
IEnumerable
的任何类型。这包括实现
IEnumerable
的类型

链接页面上的注释解释了为什么文档不显示
System.Array
implementing
IEnumerable

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

stringExcept = Enumerable.Except(listThree, listFour).