2011-11-29 77 views
1

我想有多個字符串鍵的數據結構。爲此,我嘗試使用string []元素創建一個Dictionary。但這樣做的containsKey似乎沒有如我所料的工作:字典的containsKey似乎並不與字符串工作[]鍵

Dictionary<string[], int> aaa = new Dictionary<string[], int>(); 
int aaaCount = 0; 
aaa.Add(new string[] { string1, string2 }, aaaCount++); 

if (!aaa.ContainsKey(new string[] { string1, string2 })) 
{ 
    aaa.Add(new string[] { string1, string2 }, aaaCount++); 
} 

我看到有在AAA級兩個項目的代碼,而我期待只有一個以上的執行之後。這是預期的行爲?我如何確保字典中沒有重複的條目?

注:我嘗試同樣與列表以及(列表,結果是相同的 - Contains方法並沒有真正與串[]工作)

回答

2

如果你想使用string[]作爲TKey,你應該通過IEqualityComparer<string[]>constructor of Dictionary。因爲否則字典使用標準比較爲TKey和在string[]情況下,它只是因此比較引用string[]是引用類型。你必須自己實現IEqualityComparer。

(實施是相當幼稚的,我提供它只是作爲起點)

public class StringArrayComparer : IEqualityComparer<string[]> 
{ 
    public bool Equals(string[] left, string[] right) 
    { 
     if (ReferenceEquals(left, right)) 
     { 
      return true; 
     } 

     if ((left == null) || (right == null)) 
     { 
      return false; 
     } 

     return left.SequenceEqual(right); 
    } 

    public int GetHashCode(string[] obj) 
    { 
     return obj.Aggregate(17, (res, item) => unchecked(res * 23 + item.GetHashCode())); 
    } 
} 
+0

請勿使用XOR;相反,使用'res * 23 + item.GetHashCode()'之類的東西。 http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode – SLaks

+0

嗯,我提到的實現相當幼稚:)無論如何謝謝爲了您的評論!我更新了答案,以免混淆任何人。 –

2

因爲數組是引用類型,即要基於陣列內的值的檢查參考(同一性)平等,不平等。當你創建一個新的陣列相同的值的陣列本身仍然是兩個不同的對象,所以ContainsKey返回false。

使用數組作爲字典鍵是有點...奇數。你想在這裏映射什麼?可能有更好的方法來做到這一點。

2

你需要創建一個IEqualityComparer<string[]>,並把它傳遞給字典的構造。

這告訴字典如何對鍵進行比較。
默認情況下,它是按引用比較它們。

+1

[StructuralComparisons.StructuralEqualityComparer(http://msdn.microsoft:它可以通過以下方式進行.com/en-us/library/system.collections.structuralcomparisons.structuralequalitycomparer.aspx)應該可以工作。 –

+0

我該怎麼做?一個例子會很好。謝謝 – rizter

+0

@RickSladkey:其實不會,因爲它是弱類型。 – SLaks

0

你可能會更好,如果你的應用程序支持,到字符串數組合併成一個字符串。

我們有許多情況下,兩條信息唯一標識的收集和在這些情況下的記錄,我們加入使用不應該要麼字符串值這兩個字符串(即CHAR(1))。

由於它通常是一個正在添加的類實例,因此我們讓類指定密鑰的生成,以便添加到集合的代碼只需要擔心檢查單個屬性(即CollectionKey)。