C# IEnumerable与数组的关系
是什么使.Net IEnumerable如此特殊,以至于像数组这样的编译器类型可以作为参数传递,而它是类库接口。背景中有某种继承吗 当数组可以互换地替换集合或IEnumerable作为参数时,实际会发生什么情况:C# IEnumerable与数组的关系,c#,.net,C#,.net,是什么使.Net IEnumerable如此特殊,以至于像数组这样的编译器类型可以作为参数传递,而它是类库接口。背景中有某种继承吗 当数组可以互换地替换集合或IEnumerable作为参数时,实际会发生什么情况: public void DoJob(IEnumerable<Job> jobs) { } 由于您来自Java,我将首先告诉您,在C中,有一个统一的类型系统,其中每个类型都派生自对象,而在Java中则有特殊的原语 所以在C中,数组只是另一种类型。谁说他们不能实现接口?他们可
public void DoJob(IEnumerable<Job> jobs)
{
}
由于您来自Java,我将首先告诉您,在C中,有一个统一的类型系统,其中每个类型都派生自对象,而在Java中则有特殊的原语 所以在C中,数组只是另一种类型。谁说他们不能实现接口?他们可以!编译器提供的只是一些用于创建它们的语法。实际上,数组的类型是 声明如下:
public abstract class Array : ICloneable, IList, ICollection,
IEnumerable, IStructuralComparable, IStructuralEquatable
看到了吗
编辑:
对于IEnumerable,我们可以在语言规范中找到它:
第12.1.2节:
一维数组T[]实现该接口
System.Collections.Generic.IList简称IList及其基
接口
IList实现IEnumerable。IEnumerable是一个接口,您所指的是多态性
NET中的数组、列表、集合和许多其他类型至少有一个基本IEnumerable接口。如果设置参数request Job[],则只能使用Job数组,这意味着必须先将列表或其他集合转换为数组,然后才能将其传递给参数。这意味着该方法,希望是处理和期望数组的特定原因。如果该方法不关心集合、列表或数组的类型,只想遍历这些项,那么它应该在继承树中查找较低的位置,以便许多类型都可以使用该方法。使方法IEnumerable允许该方法处理从IEnumerable派生的任何类型,在本例中,T是Job类型
知道了这一点,列表、ObservableCollection、Job[]或带有select of Job的linq查询加上更多可以使用此方法 数组在.NET中是一种特殊情况,因为不允许直接从数组类继承 从: 一维数组实现IList、ICollection、IEnumerable、IReadOnlyList和IReadOnlyCollection通用接口。这些实现在运行时提供给数组,因此,通用接口不会出现在数组类的声明语法中
这是因为.NET 1.0中不存在泛型,为了防止破坏更改,必须应用编译器黑客技术。因为数组实现IEnumerable。这有点像问为什么香蕉是水果?IEnumerable是接口,数组实现了这个接口,仅此而已。也许理解四人组迭代器模式会有所帮助?我来自Java世界,那么,默认情况下使用[]声明的本机数组是复杂类型吗?我知道.Net中的其他类型也是如此。在.Net中,该数组类被编译器用作实现,以编译任何[]用法。看这里:虽然我没有看到里面有IEnumerable;数组的类型不是System.array,正如您在检查typeofT[]时看到的那样。但是它的基本类型是System.Array,它实现了一些接口,包括IEnumerable。您的回答是正确的,但是您忘记了@Camilo解释的大警告。。。NET对数组使用了一些特殊的技巧。我知道编译器在后台做了一些事情,但这就是原因,如果它所做的只是为带有[]的数组类提供语法的话。谢谢。@DavidG对了,我错过了。添加了规范中的一些引用。为什么更改数组类以实现泛型集合是一个突破性的更改?如果您无法编写从数组派生的类,那么开发人员编写的任何类都不需要更新以实现泛型集合类中的方法。
public abstract class Array : ICloneable, IList, ICollection,
IEnumerable, IStructuralComparable, IStructuralEquatable