dictionary.TryGetValue vs FirstOrDefault

Tja*_*alt 1 c# linq dictionary compare tuples

根据MSDN文档,一个Tuple对象Equals方法将使用两个Tuple对象的值.

为什么以下内容不会产生相同的结果:

[Test]
public void TestTupleWithDictionary() 
{
    Dictionary<Tuple<string, string>, string> values = new Dictionary<Tuple<string, string>, string>();

    values.Add(new Tuple<string, string>("1", "1"), "Item 1");
    values.Add(new Tuple<string, string>("1", "2"), "Item 2");

    Assert.IsNotNull(values.FirstOrDefault(x => x.Key == new Tuple<string, string>("1", "2")));

    string value;
    values.TryGetValue(new Tuple<string, string>("1", "2"), out value);

    Assert.IsNotNullOrEmpty(value);
}
Run Code Online (Sandbox Code Playgroud)

为什么values.FirstOrDefault(x => x.Key == new Tuple<string, string>("1", "2"))回到null这里为values.TryGetValue(new Tuple<string, string>("1", "2"), out value);找到正确的键和返回值?

Jon*_*eet 8

你正在使用==,它没有超载Tuple<,>,因此它使用了引用标识检查...并且当你构造了一个新的元组时,它将永远不会成立.

这是正确的,但不受欢迎:

// Don't do this!
values.FirstOrDefault(x => new Tuple<string, string>("1", "2").Equals(x.Key))
Run Code Online (Sandbox Code Playgroud)

那会:

  • 在每次迭代时创建一个新元组
  • 必须查看每个条目,直到找到匹配的一个,这是O(N)操作...与字典查找的正常O(1)操作进行比较

  • @TjaartvanderWalt:在每次迭代中构建*一个*新元组,而不是新元组.假设没有哈希冲突,`TryGetValue`将使用哈希码在恒定时间内查找匹配条目. (2认同)