需要解释我丢失的代码输出

时间:2014-03-05 14:40:58

标签: c# .net collections foreach

我目前正在学习C#的过程,我需要一个解释。对于经验丰富的人来说,这可能是合乎逻辑且简单的,但我认为代码应该以这种方式工作而不是。

我正在尝试使用命名迭代器使用 foreach 循环打印CarcarArrayGarage内的所有GetTheCars个对象,但是当我传递< em> false 值为static void Main(string[] args) { Garage carLot = new Garage(); foreach (Car c in carLot.GetTheCars(false)) { Console.WriteLine("{0} is going {1} MPH", c.PetName, c.CurrentSpeed); } Console.WriteLine(); foreach (Car c in carLot.GetTheCars(true)) { Console.WriteLine("{0} is going {1} MPH", c.PetName, c.CurrentSpeed); } } 方法并输入else else块,没有任何反应。反向打印阵列工作正常。这是代码..

主要方法:

class Garage : IEnumerable
{
    private Car[] carArray = new Car[4];

    public Garage()
    {
        carArray[0] = new Car("Rusty", 30);
        carArray[1] = new Car("Clunker", 55);
        carArray[2] = new Car("Zippy", 30);
        carArray[3] = new Car("Fred", 30);
    }

    public IEnumerator GetEnumerator()
    {
        foreach (Car c in carArray)
        {
            yield return c;
        }
    }

    public IEnumerable GetTheCars(bool ReturnReversed)
    {
        if (ReturnReversed)
        {
            for (int i = carArray.Length; i != 0; i--)
            {
                yield return carArray[i-1];
            }
        }
        else
        {
            GetEnumerator();
        }
    }

车库类:

GetEnumerator()

在else语句中的book示例中,相同的代码编写为else { foreach (Car c in carArray) { yield return c; } } 方法:

图书代码差异:

GetEnumerator()

我以为我可以重用本书前一个例子中使用的{{1}}方法中的代码,但它没有打印出来。如果有人能解释我为什么我会感激,欢呼并提前感谢!

2 个答案:

答案 0 :(得分:6)

您在GetEnumerator区块中调用else,但这不会自动产生任何结果。如果你有类似的东西会很好:

// This doesn't actually work!
yield all carArray;

...但是C#中没有这样的构造。你可以使用:

else
{
    using (var iterator in GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            yield return iterator.Current;
        }
    }
}

或跳过GetEnumerator

else
{
    foreach (var var in carArray)
    {
        yield return car;
    }
}

......但显然这很难看。

所做的是将代码分开,以便在需要自定义顺序时只使用迭代器块(带yield return语句的方法):

// Made return type generic, and improved the name
public IEnumerable<Car> GetTheCars(bool reverseOrder)
{
    return reverseOrder ? GetTheCarsReversed() : carArray;
}

private IEnumerable<Car> GetTheCarsReversed()
{
    for (int i = carArray.Length; i != 0; i--)
    {
        yield return carArray[i - 1];
    }
}

如果您没有要求反转顺序,那么在直接返回数组引用方面确实存在缺点......然后调用者可以转换为Car[]并修改数组。然而,这可能是一个不需要了解的细微差别。

答案 1 :(得分:3)

我感谢此代码可能只是您的一项实验,但要以相反的顺序获取任何IEnumerable,您只需使用Linq扩展方法Reverse

using System.Linq;

...

foreach (var c in carLot.GetTheCars().Reverse())
{
    Console.WriteLine("{0} is going {1} "MPH", c.PetName, c.CurrentSpeed);
}

然后可以写出GetTheCars()方法:

public IEnumerable<Car> GetTheCars()
{
    return carArray;
}