2016-07-14 76 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对象,每次运行时它都会生成一个新列表。 –

相关问题