将数组转换为 IEnumerable<T>

Posted

技术标签:

【中文标题】将数组转换为 IEnumerable<T>【英文标题】:Casting array to IEnumerable<T> 【发布时间】:2011-08-24 09:35:12 【问题描述】:

假设您有一个基本的Employee 类:

class Employee

   public string Name;
   public int Years;
   public string Department;

然后(在一个单独的类中)我有以下代码片段(我想我理解除了最后一个):

我相信下面的代码片段可以工作,因为数组初始化器创建了一个 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"  ;

我不确定为什么这个代码片段有效? IEnumerable&lt;Employee&gt; 继承自 IEnumerable(并覆盖(或重载?)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&lt;Employee&gt; 但我一直认为,当您需要将类型转换为更具体的类型时,您需要显式转换。

也许我在这里的理解中遗漏了一些简单的东西,但有人可以帮助我理解这一点。

谢谢。

【问题讨论】:

@Aliostad:它就在workforceThree 片段的下方。 【参考方案1】:

来自the documentation:

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

因此,您的Employee[] 实现了IEnumerable&lt;Employee&gt;

【讨论】:

澄清一下,实现它的不是 Array 类,而是任何 T 的 T[]。【参考方案2】:

员工数组默认实现IEnumerable&lt;Employee&gt;IEnumerable

【讨论】:

【参考方案3】:

当某些句子需要向下转换时,需要显式转换。那就是将对象转换为更专业的类型 - 如果对象属于这种专门的类型 - 。

另一方面,向上转换(转换为不那么专业的类型)永远不需要显式转换,但您可以显式地进行(只是没用)。

由于 Array 实现了 IEnumerableIEnumerable&lt;T&gt;,因此您正在代码中进行 向上转换,这意味着_您不需要显式转换为 IEnumerable&lt;T&gt;

【讨论】:

我不同意。在某些情况下,您需要明确的向上转型。作为示例函数覆盖: void DoStuffs(IEnumerable objects) ... void DoStuffs(params T[] objects) DoStuffs((IEnumerable) objects); @Orace 这不完全是向上转型...这是一个编译器帮助让它调用所需的重载...你同意吗? ;) 这是一个方法重载解决问题。 @Orace 嗯,这是一个向上转换,但我的意思是你需要明确的“转换”来调用所需的重载......

以上是关于将数组转换为 IEnumerable<T>的主要内容,如果未能解决你的问题,请参考以下文章

将 IEnumerable<Ienumerable<T>> 转换为 Dictionary<key,IEnumerable<T>>

将 IEnumerable<T> 转换为 List<T>

无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”

将 DataTable 转换为 IEnumerable<T>

将 DataRowCollection 转换为 IEnumerable<T>

如何将 IEnumerable<t> 或 IQueryable<t> 转换为 EntitySet<t>?