2011-08-24 70 views
64

假设你有一个基本的Employee类这样:铸造阵列的IEnumerable <T>

class Employee 
{ 
    public string Name; 
    public int Years; 
    public string Department; 
} 

然后(在一个单独的类)我有下面的代码片段(我想我明白所有,但最后一个):

我相信下面的代码片段的工作原理是因为数组initiliser创建了一个Employee对象的数组,它与被分配给的劳动力变量的类型相同。

Employee[] workforceOne = new Employee[] { 
    new Employee() { Name = "David", Years = 0, Department = "software" }, 
    new Employee() { Name = "Dexter", Years = 3, Department = "software" }, 
    new Employee() { Name = "Paul", Years = 4, Department = "software" } }; 

然后我有下面的代码片段。我相信这是有效的,因为Employee对象隐含数组是实现IEnumerable的Array()类的实现。因此,我相信这就是为什么数组可以分配给IEnumerable?

IEnumerable workforceTwo = new Employee[] { 
    new Employee() { Name = "David", Years = 0, Department = "software" }, 
    new Employee() { Name = "Dexter", Years = 3, Department = "software" }, 
    new Employee() { Name = "Paul", Years = 4, Department = "software" } }; 

然后,我有这样的代码片段:

IEnumerable<Employee> workforceThree = new Employee[] { 
    new Employee() { Name = "David", Years = 0, Department = "software" }, 
    new Employee() { Name = "Dexter", Years = 3, Department = "software" }, 
    new Employee() { Name = "Paul", Years = 4, Department = "software" } }; 

我不知道为什么这个代码片段的作品?从IEnumerableIEnumerable<Employee>继承(α和覆盖(或过载)的GetEnumerator()方法),但不应因此,我需要用于上述的铸造这样的工作:

//The cast does work but is not required 
IEnumerable<Employee> workforceFour = (IEnumerable<Employee>)new Employee[] { 
    new Employee() { Name = "David", Years = 0, Department = "software" }, 
    new Employee() { Name = "Dexter", Years = 3, Department = "software" }, 
    new Employee() { Name = "Paul", Years = 4, Department = "software" } }; 

似乎阵列正被隐式地向下从IEnumerable类型投射到IEnumerable<Employee>,但我一直认为,当您需要将类型转换为更具体的类型时,您需要进行明确的投射。

也许我在我的理解中错过了一些简单的东西,但是有人可以帮我理解这个。

谢谢。

+0

这里有什么问题? – Aliostad

+3

@Aliostad:它位于'workforceThree'片段的正下方。 – Heinzi

+3

+1好问题! – Gishu

回答

93

the documentation

在.NET Framework 2.0版,Array类实现System.Collections.Generic.IList<T>System.Collections.Generic.ICollection<T>,和System.Collections.Generic.IEnumerable<T>通用接口。这些实现在运行时提供给数组,因此对文档构建工具不可见。因此,通用接口不会出现在Array类的声明语法中,并且只有通过将数组转换为通用接口类型(显式接口实现)才能访问的接口成员没有参考主题。

因此,您的Employee[]执行IEnumerable<Employee>

+3

为了澄清,它不是Array类实现它,它是T []任何T. [ – IllidanS4

4

需要员工的默认工具IEnumerable<Employee>以及IEnumerable

3

明确的转换数组的时候有些句子必须downcasted。这就是将一个对象转换为更专用的类型 - 如果对象是这种特殊类型的 - 。

另一方面,upcasting(铸造到一个不太专业化的类型),永远不会需要一个明确的演员,但你可以明确地做到这一点(这只是无用的)。

,数组实现IEnumerableIEnumerable<T>,你做你的代码的上溯造型,意思_you并不需要显式转换为IEnumerable<T>

+3

]我不同意。在某些情况下,您需要明确的上传。作为一个示例功能控制装置: 空隙DoStuffs(IEnumerable的对象){...} 空隙DoStuffs(PARAMS T []对象){DoStuffs((IEnumerable的)对象); } – Orace

+2

@Orace这不完全是一个upcast ...这是一个编译器的帮助,让它调用期望的过载...你同意吗? ;)这是一个重载方法问题。 –

+0

@Orace嗯,这是一个upcast,但我的意思是,你需要明确的“铸”来调用所需的重载... –