【问题标题】:Casting array to IEnumerable<T>将数组转换为 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 片段的下方。

标签: c# arrays generics casting


【解决方案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 嗯,这是一个向上转换,但我的意思是你需要明确的“转换”来调用所需的重载......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多