3

この単純なコードに問題があり、c# がこのように動作する理由がわかりません。

問題は、リスト内でリストを使用するときに、c# が値​​の代わりに Linq 式参照を使用することです。

番号のループでは、リストに基づいて番号を選択します。それらはすべて存在するため、すべての番号をリスト {1,2,3} に追加する必要があります。

数値ループ内に {1,2,3} が表示されているコンソールからの出力を見ると、動作は問題ありません。

問題はリストのループにあります。ここでは、Linq は最後の番号のみをリストに追加するように見えるため、{3,3,3} を出力します。

リスト内にintのリストが必要ないことはわかっていますが、それは非常に奇妙であることを証明するためのものです。これは既知の「バグ」ですか?

編集:これは、5.0 より前の c# で動作するはずの方法のようです。C# 5.0 (VS2012+ コンパイラ) では、この動作は期待どおりに変更されました。

static void Main()
{
    var list = new List<IEnumerable<int>>();
    var numbers = new[] {1, 2, 3};
    var numbers2 = new[] {1, 2, 3};

    foreach (var number in numbers)
    {
        var result = from s in numbers2
                     where s == number
                     select s;

        Console.WriteLine(result.First()); // outputs {1,2,3}
        list.Add(result);
    }

    foreach (var num in list)
    {
        Console.WriteLine(num.First()); // outputs {3,3,3}
    }
}

出力

1 2 3 3 3 3

4

4 に答える 4

2

クエリが実行されると、== 3 になります。

これは、最初の foreach ループが既に実行されており、numberへの最後の代入が事実上 3 であるためです。

LINQ クエリは、必要に応じて遅延実行されます (たとえば、 a を呼び出す場合ToList())。

これは奇妙な結果ではありません。

ちなみに、C# 5.0 (VS2012+ コンパイラ) では、この動作は予想どおりに変更されています。

于 2013-10-16T12:55:13.947 に答える
1

linq 式は、その結果が必要な場合にのみ実行されます。

そう

var result = from s in numbers2
where s == number
select s;

結果の値が必要なときに実行されます。ただし、式をすぐに評価したい場合は、式から結果を取得してオブジェクトを作成する必要があります。

お気に入り

var result = (from s in numbers2
where s == number
select s).ToList();

適切なフローを見たい場合は、「from s in numbers2....」の行にブレークポイントを設定し、いつヒットするかを確認します...

それが役に立てば幸い...

于 2013-10-16T12:57:26.060 に答える