2016-07-14 75 views
0

我有一個奇怪的錯誤。我將數據與GUID配對,以便稍後識別它們並更改原始數據。這兩個Guids有什麼不同?

我能夠將真正複雜的問題重新創建爲一個更簡單的問題,我可以在這裏問,因此我使用字符串作爲數據。考慮一下這個例子:

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中的輸出窗口,你會看到兩個GUID的,就像兩個:

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

注:他們是不一樣的

現在我的問題是:

如何,或爲什麼他們甚至不同?

我創建一個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'時被調用兩次。 – juharr

+3

您正在創建兩個LINQ查詢 - 每次訪問時都會重新運行'Select' lambda中的代碼。 –

+0

@Damien_The_Unbeliever哦 - 看起來像懶惰評估再次讓我再次:p – Mafii

回答

3

我想你已經遇到了Linq的魔力。試試這個:

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

看看你是否得不到相同的值。每次在您的代碼中執行Linq的Select,每次都會產生一個新的GUID。我想,實際的術語是投影和實現。

+0

我認爲解決了它是的。那是因爲linq的部分是用惰性執行(在請求數據時執行的)實現的嗎? – Mafii

+0

@Mafii是的,這正是發生了什麼事情。 – Kyle

+1

解釋,在原始代碼中,'List1'不是一個列表,而是一個IEnumerable對象,每次運行時它都會生成一個新列表。 –

相關問題