5

以下の C# コードでは、最初の印刷セットが次の出力を生成するのはなぜですか?

C
C
C

しかし、それに相当するLINQは次の出力を生成します

A
B
C

出力の最初のセットを理解しています - ループを出るときに最後の値を取りますが、従来のループと同等の LINQ の間に一貫性があるべきだと私には思えますか? - どちらの場合も CCC または ABC を出力する必要がありますか?

public static void Main(string[] str)
    {
        List<string> names = new List<string>() {"A", "B", "C"};

        List<Action> actions = new List<Action>();
        foreach(var name in names)
        {
            actions.Add(() => Console.WriteLine(name));
        }

        foreach(var action in actions)
        {
            action.Invoke();
        }

        List<Action> actionList = names.Select<string, Action>(s => () => Console.WriteLine(s)).ToList();

        foreach(var action in actionList)
        {
            action.Invoke();
        }
    }
4

2 に答える 2

7

これは、ループ変数を閉じているためです。リッパート以上にうまく説明することはできません。(誰でもできますか?) まだ混乱している場合は、時間をかけてじっくり考えて、彼のブログのコメントを読んでください。

これは、Linq を使用する際によくある間違いです。ほぼ全員がそれを達成しました。C# 5.0 (Visual Studio 2012 で使用) コンパイラでは、この動作が変更されていますが、できることなら避けるべきです。最初のループを次のように書き直すことができます。

foreach(var name in names)
    {
        var currentName = name;
        actions.Add(() => Console.WriteLine(currentName));
    }

そして問題はなくなります。

于 2013-06-01T02:30:31.163 に答える