2

在这个实现中,hand 是否每次都会被评估并返回另一个列表?

foreach (Card card in hand.Cards)
{ 

}

我们应该用以下实现替换上面的实现吗?

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

} 
4

4 回答 4

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
于 2012-09-01T14:18:32.477 回答
0

不,这两者之间没有区别。此外,如果它们用于 EF,它们是相同的查询。也在下面的语法中:

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

}

hand.Cards.AsEnumerable()首先评估并将保存在临时变量中,实际上这不会在每次迭代中发生。

PS:一般foreach循环中不需要调用AsEnumerable,我刚才提到这个是为了详细说明foreach求值。

于 2012-09-01T14:18:18.053 回答
0

没有区别。

但是如果你hand.Cards在其他代码中使用,是的,第二个应该没问题。

于 2012-09-01T14:19:46.853 回答
0

您在上面发布的两个代码片段是相同的。当您通过实现 IEnumerable 接口的集合进行枚举时,它使用该GetEnumerator方法循环遍历项目,并且不会创建对象的重复副本。

上面唯一的区别是您正在创建第二个变量,该变量包含对原始集合的相同引用,在这种情况下这对您没有任何好处。

于 2012-09-01T14:20:49.863 回答