2016-07-14 10 views
0

Ich habe einen seltsamen Fehler. Ich verknüpfe Daten mit Guids, um sie später zu identifizieren und das Original zu ändern.Wie unterscheiden sich diese beiden Guids?

Ich war in der Lage, das wirklich komplexe Problem in eine einfachere zu rekonstruieren, die ich hier fragen kann, daher verwende ich Strings als Daten. Betrachten Sie dies als ein Beispiel:

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(); 

Nehmen Sie einfach das Stück Code und führen Sie es aus. Im Ausgabefenster von Visual Studio sollten Sie zwei guids sehen, wie diese beiden:

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

Hinweis: Sie sind nicht die gleichen

Nun meine Frage:

Wie oder warum sind sie sogar anders?

Ich erstelle ein guid hier:

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

Und dann wird es nur kopiert werden:

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

Warum diese unterschiedlich sind?

Wie kann ich das beheben?

+8

Verzögerte Ausführung. Setzen Sie eine 'ToList' am Ende der' list1' Zuweisung und es wird der gleiche Wert sein. Grundsätzlich wird 'Guid.NewGuid' zweimal aufgerufen, wenn Sie' First' auf 'list1' und dann auf' list2' aufrufen. – juharr

+3

Sie erstellen zwei LINQ-Abfragen - jedes Mal, wenn Sie darauf zugreifen, führen Sie den Code erneut im Select-Lambda aus. –

+0

@Damien_The_Unbeliever oh - Scheint wie Lazy-Evaluation rekt mich noch einmal: p – Mafii

Antwort

3

Ich denke, Sie haben die Magie von Linq getroffen. Versuchen Sie folgendes:

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

und sehen Sie, wenn Sie nicht identische Werte erhalten. Linqs Auswahl wird jedes Mal in Ihrem Code ausgeführt, was jedes Mal zu einer neuen Guid führt. Die eigentlichen Begriffe sind Projektion und Realisierung, denke ich.

+0

Ich denke, dass es ja gelöst hat. Ist das, weil Teile von Linq mit Lazy Execution implementiert sind (ausgeführt, wenn Sie die Daten anfordern)? – Mafii

+0

@Mafii Ja, genau das passiert. – Kyle

+1

Zur Erläuterung: Im ursprünglichen Code war 'List1' keine Liste, sondern ein IEnumerable-Objekt, das bei jeder Ausführung eine neue Liste generiert. –