在這個實現中,每次都會評估hand並返回另一個列表?IEnumerable evaluation
foreach (Card card in hand.Cards)
{
}
我們應該用下面的代碼替換上面的實現嗎?
var cards = hand.Cards;
foreach (Card card in cards)
{
}
在這個實現中,每次都會評估hand並返回另一個列表?IEnumerable evaluation
foreach (Card card in hand.Cards)
{
}
我們應該用下面的代碼替換上面的實現嗎?
var cards = hand.Cards;
foreach (Card card in cards)
{
}
不,實際上這兩個代碼片段會導致相同的代碼。 在下面的代碼片段:
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
不,這兩者之間沒有區別。此外,如果他們是EF,他們是相同的查詢。還在下面的語法:
foreach (Card card in hand.Cards.AsEnumerable())
{
}
的hand.Cards.AsEnumerable()
將首先進行評估,將保存在臨時變量,其實這個習慣在每次迭代中發生。 P:一般來說,不需要在foreach循環中調用AsEnumerable,我剛纔提到了這個來詳細說明foreach的評估。
沒有區別。
但是如果在其他代碼中使用hand.Cards
,那麼第二個應該沒問題。
上面發佈的兩個代碼片段是相同的。當您通過實現IEnumerable接口的集合枚舉時,它使用GetEnumerator
方法遍歷項目,並且不會創建對象的重複副本。
以上唯一的區別是您正在創建第二個變量,該變量與原始集合保持相同的引用,在這種情況下,這對您沒有任何好處。
謝謝你詳細的答案你能解釋yield函數嗎?這個例子中的 –
-不是返回一個對象列表(卡片)並且構建它們(這可能需要時間),而是使用良率。 yield一次返回一個對象 - 這是非常方便的,因爲對象一個接一個地被處理。在這種情況下,對象列表可能會變得非常大,可能會花費大量時間來開始處理第一個對象。你會發現更詳細的msdn產量的解釋:http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx – MaciekTalaska
忘了補充:我上面的示例我只是想告訴你,它不會不管你選擇哪種方法 - 你總是得到兩張牌:Ace和King。 – MaciekTalaska