2016-02-03 97 views
1

根據MSDN documentation,Tuple objects Equals方法將使用兩個Tuple對象的值。dictionary.TryGetValue vs FirstOrDefault

爲什麼以下不會產生相同的結果:

[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); 
} 

爲什麼values.FirstOrDefault(x => x.Key == new Tuple<string, string>("1", "2"))回報null其中作爲values.TryGetValue(new Tuple<string, string>("1", "2"), out value);找到正確的鍵和返回值?

回答

7

您使用==,這是不重載Tuple<,>,所以它的使用參考身份檢查......和你建造一個新的記錄,這將永遠是真實的。

這將是正確,但不可取:

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

那倒:

  • 創建在每次迭代
  • 一個新的元組必須通過每個條目看,直到它找到了匹配一個,這是一個O(N)操作...與字典查找的正常O(1)操作相比較
+0

這與'values.TryGetValue(新元組(「1」,「2」),out值)有何不同?'因爲我也在構造一個新的元組 –

+2

@TjaartvanderWalt: *新元組,每次迭代都不是新元組。假設沒有散列衝突,'TryGetValue'將使用散列碼在常量時間內查找匹配條目。 –