2012-09-01 32 views
2

在這個實現中,每次都會評估hand並返回另一個列表?IEnumerable evaluation

foreach (Card card in hand.Cards) 
{ 

} 

我們應該用下面的代碼替換上面的實現嗎?

var cards = hand.Cards; 
foreach (Card card in cards) 
{ 

} 

回答

4

不,實際上這兩個代碼片段會導致相同的代碼。 在下面的代碼片段:

foreach (Card card in hand.Cards) 
{ 

} 

hand.Cards將是一次調用。

編輯:

我創建了一個小片段,我希望將表明,沒有什麼區別可言:

void Main() 
{ 
    Hand hand = new Hand(); 
    foreach(var card in hand.Cards()) 
    { 
     Console.WriteLine("{0}", card); 
    } 

    var allCards = hand.Cards(); 
    foreach(var anotherCard in allCards) 
    { 
     Console.WriteLine("{0}", anotherCard); 
    } 
} 

public class Card 
{ 
private string _cardName; 
public Card(string cardName) 
    { 
     this._cardName = cardName; 
    } 

    public override string ToString() 
    { 
     return this._cardName; 
    } 
} 

public class Hand 
{ 
    public IEnumerable<Card> Cards() 
    { 
     yield return new Card("Ace"); 
     yield return new Card("King"); 
    } 
} 

的otuput(兩種方法)如下:

Ace 
King 
Ace 
King 
+0

謝謝你詳細的答案你能解釋yield函數嗎?這個例子中的 –

+0

-不是返回一個對象列表(卡片)並且構建它們(這可能需要時間),而是使用良率。 yield一次返回一個對象 - 這是非常方便的,因爲對象一個接一個地被處理。在這種情況下,對象列表可能會變得非常大,可能會花費大量時間來開始處理第一個對象。你會發現更詳細的msdn產量的解釋:http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx – MaciekTalaska

+0

忘了補充:我上面的示例我只是想告訴你,它不會不管你選擇哪種方法 - 你總是得到兩張牌:Ace和King。 – MaciekTalaska

0

不,這兩者之間沒有區別。此外,如果他們是EF,他們是相同的查詢。還在下面的語法:

foreach (Card card in hand.Cards.AsEnumerable()) 
{ 

} 

hand.Cards.AsEnumerable()將首先進行評估,將保存在臨時變量,其實這個習慣在每次迭代中發生。 P:一般來說,不需要在foreach循環中調用AsEnumerable,我剛纔提到了這個來詳細說明foreach的評估。

0

沒有區別。

但是如果在其他代碼中使用hand.Cards,那麼第二個應該沒問題。

0

上面發佈的兩個代碼片段是相同的。當您通過實現IEnumerable接口的集合枚舉時,它使用GetEnumerator方法遍歷項目,並且不會創建對象的重複副本。

以上唯一的區別是您正在創建第二個變量,該變量與原始集合保持相同的引用,在這種情況下,這對您沒有任何好處。