C# - 层次迭代的工作方式不同

时间:2009-08-20 12:50:21

标签: c#

当我对以下声明进行迭代时:

Car [] cars = new Car [2];
cars [0] =新车{Speed = 100,Color =“green”};
汽车[1] =新车{速度= 200,颜色=“橙色”};

使用“foreach”我没有问题来迭代Car Array

但如下所示:

公共类CarStore:Car     {
        Car [] m_collection = new Car [2];

    public CarStore()
    {
        m_collection[1] = new Car { Speed = 100, Color = "red" };
        m_collection[2] = new Car { Speed = 200, Color = "yellow" };
    }

}


现在我想使用:

CarStore m_Store = new CarStore();

foreach(m_Store中的car myCar),迭代将无法工作,直到我使用IEnumerator

<小时/> 我的问题是:

  1. CLR如何在内部对待它们?第一种情况它使用System.Array,会发生什么       第二次申报..?
  2. 我真的不适合在OOps世界中编码吗?,因为我不知道这些基本的东西?

3 个答案:

答案 0 :(得分:4)

foreach无法神奇地推断您正在构建一个可枚举的集合。它的作用是看它是否可以调用返回GetEnumerator的{​​{1}}方法。如果它不能调用这样的方法,编译器会抱怨。

如果您希望能够在自己的对象上使用IEnumerator,则必须提供GetEnumerator实施:

foreach

答案 1 :(得分:4)

CLR对foreach一无所知。这都是关于C#编译器的:

  • 当C#编译器看到一个数组时,它将使用Length和数组索引器迭代它。
  • 当C#编译器看到实现IEnumerable<T>IEnumerable的内容时,它将使用GetEnumerator,然后使用MoveNext / Current(以及Dispose结束)。
  • 当C#编译器看到某个GetEnumerator方法被声明为返回具有适当MoveNext() / Current成员的东西时,它会使用它 - 但这实际上是为了给出类型 - 安全集合pre-generics,并未在新代码中使用。

不知道这并不意味着你不适合编程 - 这只是意味着你应该在进一步学习之前阅读一本关于C#的好书。无知与愚蠢之间的区别在于无知可以得到纠正:)


基本上你应该实施IEnumerable<Car>

public class CarStore : IEnumerable<Car> { 
    Car[] m_collection = new Car[2];

    public CarStore()
    {
        // Indexes adjusted - C# arrays are 0-based
        m_collection[0] = new Car { Speed = 100, Color = "red" };
        m_collection[1] = new Car { Speed = 200, Color = "yellow" };
    }

    public IEnumerator<Car> GetEnumerator() {
        return m_collection.GetEnumerator();
    }

    public IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }
}

仅仅使用没有实现IEnumerable<T>的方法就足以让编译器使用foreach,但是使用泛型,而不是实现IEnumerable<T>没有任何好处,这样你的类就可以在LINQ等中使用了。

顺便说一句,我已删除CarStore : Car的想法,因为CarStore Car ...你的实际情况当然可能更合理。

答案 2 :(得分:0)

在你的例子中,你可以迭代cars数组,因为它是一个数组,显然实现了IEnumerable (参见下面的Jons评论)。您的CarStore类是Car类型的子类(我假设它是对象的子类,并且不实现IEnumerable接口)。您无法枚举CarStore类,因为您没有实现IEnumerable接口。

如果您没有在CarStore类型中明确指定要枚举的内容,那么运行时应该如何计算出来?