簡體   English   中英

C#ForEach循環(循環中的字符串聲明)

[英]C# ForEach Loop (string declaration in loop)

我有這個字符串數組的名稱。

string[] someArray = { "Messi", "Ronaldo", "Bale", "Neymar", "Pele" };

foreach (string item in someArray)
  {
     Console.WriteLine(item);
  }

當我在調試模式下運行foreach行上的斷點並使用Step Into時,每次傳遞都會突出顯示字符串項,就像它再次聲明它一樣。 我想它應該只突出項目。 這是否表示每次再次聲明項目?

注意:使用VS 2012。

這里的答案很微妙,因為這個問題(意外)不清楚。 讓我通過將其分成多個問題來澄清它。

每次通過foreach循環時,循環變量是否在邏輯上重新聲明?

正如另一個答案正確指出的那樣,在C#5及更高版本中,是的。 在C#1到4中,沒有。

這種變化的可觀察結果是什么?

在C#1中,沒有辦法區分它們。 (並且規范實際上不清楚變量的聲明位置。)

在C#2中,團隊以匿名方法的形式添加了閉包。 如果有多個閉包捕獲C#2,3和4中的循環變量,它們都捕獲相同的變量,並且它們都會在循環運行時看到它變異。 這幾乎不是你想要的。

在C#5中,我們采用了重大變化來說每次循環都會聲明一個新的循環變量,因此每個閉包捕獲一個不同的變量,因此不會觀察到它的變化。

為什么每次循環時調試器都會返回循環變量聲明?

通知您循環變量正在變異。 如果你有

IEnumerable<string> someCollection = whatever;
foreach(string item in someCollection)
{
    Console.WriteLine(item);
}

這在邏輯上等同於

IEnumerable<string> someCollection = whatever;
{
    IEnumerator<string> enumerator = someCollection.GetEnumerator();
    try
    {
        while( enumerator.MoveNext() )
        {
            string item;  // In C# 4.0 and before, this is outside the while
            item = enumerator.Current;
            {
                Console.WriteLine(item);
            }
        }
    }
    finally
    {
        if (enumerator != null)
            ((IDisposable)enumerator).Dispose();
    }
}

如果您正在調試該擴展版本的代碼,您會看到調試器突出顯示MoveNextCurrent的調用。 好吧,調試器以緊湊的形式做同樣的事情; MoveNext即將被調用時,調試器突出顯示in ,因為缺少任何更好的突出顯示。 Current即將被稱之為突出item 再一次,強調什么是更好的事情?

因此,調試器突出顯示變量的事實與變量是否重新聲明無關?

正確。 它會在Current即將被調用時突出顯示變量,因為這會改變變量。 它改變變量,無論它是C#5中的新變量,還是C#4中與之前相同的變量。

我注意到你改變了我的例子以使用通用序列而不是數組。 你為什么這么做?

因為如果C#編譯器知道foreach中的集合是一個數組,它實際上只是生成一個很好的老式for循環而不是調用MoveNextCurrent以及所有這些。 這樣做通常會更快並且產生更少的收集壓力,所以這是一個全面的勝利。

但是,C#團隊希望調試體驗無論如何都要一樣。 同樣,代碼生成器in其中創建了步進點 - 這次為生成的for循環變量進行了變異 - 再次,在變換foreach循環變量的代碼上。 這樣調試體驗是一致的。

這取決於您要定位的C#版本。 在C#5中,它是一個新變量。 在此之前,該變量被重用。

請參閱Eric Lippert的博客文章: http//blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx

從帖子:

更新:我們正在進行重大改變。 在C#5中,foreach的循環變量將在邏輯上位於循環內部,因此閉包每次都會關閉變量的新副本。 “for”循環不會改變。 我們現在回復您的原始文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM