我目前正在学习C#的过程,我需要一个解释。对于经验丰富的人来说,这可能是合乎逻辑且简单的,但我认为代码应该以这种方式工作而不是。
我正在尝试使用命名迭代器使用 foreach 循环打印Car
类carArray
内Garage
内的所有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}}方法中的代码,但它没有打印出来。如果有人能解释我为什么我会感激,欢呼并提前感谢!
答案 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;
}