2014-03-05 79 views
1

我目前正在學習C#的過程,我需要一個解釋。對於更有經驗的人來說,這可能是合乎邏輯和簡單的,但我認爲代碼應該以這種方式工作,而不是。需要關於我的缺少代碼輸出的解釋

我想打印出裏面carArray所有Car對象在我Garage的foreach使用命名迭代器循環,但是當我通過GetTheCars方法和else塊進入裏面,沒有任何反應。在反向打印數組很好。這是代碼..

主要方法:

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); 
     } 
    } 

車庫類:

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(); 
     } 
    } 

else語句裏面的書例如,同樣的代碼寫在GetEnumerator()方法:

書代碼不同NCE:

else 
{ 
    foreach (Car c in carArray) 
    { 
     yield return c; 
    } 
} 

我想我可以重用在書的前面的例子中使用的方法GetEnumerator()裏面的代碼,但它打印出什麼。如果有人能解釋我爲什麼我會感激,提前歡呼和感謝!

回答

6

您在else區塊中打電話GetEnumerator,但這不會自動產生任何結果。這將是很好,如果你可以有這樣的事情:

// 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[]並修改數組。但是,這可能是一個細節,不需要知道。

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; 
}