2016-07-14 10 views
0

私は奇妙なエラーがあります。私は後でそれらを識別し、元のものを変更するためにguidsとデータをペアリングしています。これらの2つのガイドはどのように異なっていますか?

本当に複雑な問題を私がここで聞くことができるより単純なものに再現することができました。なぜ私はデータとして文字列を使用していますか?これを例として考えてみましょう。

List<string> testList = new List<string>(new[] { "haha", "wit" }); 
    var list1 = testList.Select(x => new KeyValuePair<Guid, string>(Guid.NewGuid(), x)); 
    var list2 = list1.Select(x => new KeyValuePair<Guid, string>(x.Key, x.Value)); 
    Guid xGuid = list1.First().Key; 
    Guid yGuid = list2.First().Key; 

    System.Diagnostics.Debug.Print(xGuid.ToString()); 
    System.Diagnostics.Debug.Print(yGuid.ToString()); 
    System.Diagnostics.Debugger.Break(); 

コードを取り出して実行してください。 Visual Studioの出力ウィンドウでは、ちょうどこれら二つのように、2つのGUIDを参照する必要があります

35ac8c6a-928c-46a9-a614-9d35c2427219 
d2175358-85f8-4467-be02-34932f2f4804 

注:

方法、または:を彼らは今、私の質問がある

同じではありませんなぜが違うのですか?

私はここに1つのGUIDを作成:

var list1 = testList.Select(x => new KeyValuePair<Guid, string>(Guid.NewGuid(), x)); 

をし、それが唯一のコピーされている:

var list2 = list1.Select(x => new KeyValuePair<Guid, string>(x.Key, x.Value)); 

、なぜこれらの異なるですか?

どうすればこの問題を解決できますか?

+8

遅延実行。 'List1'代入の最後に' ToList'を置くと、それは同じ値になります。基本的に 'guid.NewGuid'は、' list1'で 'First'を呼び出し、' list2'で '2回呼び出されています。 – juharr

+3

2つのLINQクエリを作成しています。アクセスするたびに、 'Select'ラムダ内でコードを再実行します。 –

+0

@Damien_The_Unbelieverああ - 怠け者評価のように思えるre:私はもう一度:p – Mafii

答えて

3

あなたはLinqの魔法に遭遇したと思います。これを試してみてください:

var list1 = (your code).ToList() 
var list2 = (your code).ToList() 

と同じ値が得られないかどうかを確認してください。 LinqのSelectは毎回あなたのコードで実行され、毎回新しいGUIDが得られます。実際の用語はProjection and Realizationです。

+0

私はそれを解決したと思います。これは、linqの一部が遅延実行で実装されているためです(データを要求するときに実行されます)。 – Mafii

+0

@Mafiiはい、まさにそれが起こっています。 – Kyle

+1

説明するには、元のコードでは、 'List1'はリストではなく、IEnumerableオブジェクトで、実行するたびに新しいリストを生成します。 –

関連する問題