2009-12-16 34 views
13

基本上,我想是這樣的:C# - 需要一個IDictionary實現,將允許null鍵

Dictionary<object, string> dict = new Dictionary<object, string>(); 
dict.Add(null, "Nothing"); 
dict.Add(1, "One"); 

是否有任何內置到基礎類庫,它允許這樣做?在添加空鍵時,上述代碼將在運行時引發異常。

感謝

+0

只是好奇,你需要這個在哪裏?謝謝 – 2009-12-16 18:58:38

回答

11

你可以儘量避免使用空,創建一個特殊的單值類,做同樣的事情。例如: - 比方說,比如你想關鍵是字符串

public sealed class Nothing 
{ 
    public static readonly Nothing Value = new Nothing(); 
    private Nothing() {} 
} 

Dictionary<object, string> dict = new Dictionary<object, string>(); 
dict.add(Nothing.Value, "Nothing"); 
dict.add(1, "One"); 

如果您打算讓您的收藏更強類型的這種方法將不能工作。由於字符串是密封的,你不能從它繼承來爲null創建一個「特殊值」替代。你的選擇變得更復雜一點。您可以:

  1. 創建一些特殊的常量值來表示「空」/「空」情況。一種哈克,肯定是一個混亂的道路。如果字典對某些實現類是完全私有的,那麼這可能是一種可行的方法,並且您可以編寫一些編碼/解碼實用程序方法,以避免傳播關鍵字在整個位置的翻譯知識。
  2. 創建您自己的IDictionary實現,該實現將內部委託給一個字典<> instance - 除了null的情況。這違反了IDictionary <>接口的文檔預期,它確實聲稱空鍵應該引發​​異常。但是,如果這是解決真正問題的唯一方法,那麼您可能會擺脫困境。這隻適用於擁有並創建字典實例的情況。
  3. 找到解決問題的方法,而不在字典中存儲「空」鍵。例如,考慮不填充字典中的空鍵,並有一些特殊情況邏輯來處理它。密鑰必須是可散列的,並且可以與底層實現一起使用,這就是爲什麼null被正常禁止的原因。

另外,你的字典鍵真的需要鍵是object?這可能會導致微妙的錯誤,因爲在您可能希望將Equals()作爲比較的基礎進行評估時使用了參考平等。

+0

這個應用程序是Component One用戶控件C1FlexGrid.ImageMap,它基本上是將存儲在網格中的值映射到圖像。基本上,我無法控制數據,其中一些是空的。 – Clyde 2009-12-16 19:00:52

+0

因此,不幸的是我不能使用像Nothing這樣的模擬對象。 – Clyde 2009-12-16 19:01:23

+0

但是,感謝== vs等於警告....您剛剛爲我節省了一些時間來追蹤不同的問題。 – Clyde 2009-12-16 19:06:12

2

NameValueCollection可以接受一個空鍵,但它不會實現IDictionary。然而,這將是很容易從DictionaryBase派生並提供添加/刪除/索引器等簡單地與內置的東西像替換空:

class MyDictionary : DictionaryBase { 
    private readonly object nullKey = new object(); 

    void Add(object key, string value) { 
     if (key == null) { key = nullKey; } 
     .. call base methods 
    } 

} 
5

這個怎麼樣?

public class NullableDictionnary<T1, T2> : Dictionary<T1, T2> 
{ 
    T2 null_value; 

    public T2 this[T1 key] 
    { 
     get 
     { 
      if (key == null) 
      { return null_value; } 
      return base[key]; 
     } 
     set 
     { 
      if (key == null) 
      { null_value = value; } 
      else 
      { base[key] = value; } 
     } 
    } 
} 
+8

小心所有其他功能,你現在已經失效 - 計數,添加,清除,ContainsKey,ContainsValue等... 我的意思是,如果你只是黑客,好吧,但我不喜歡創建「NullableDictionary」類,如果你打算這樣做。如果黑客明顯是黑客攻擊,那麼稍後您不太可能受到攻擊。 – phillipwei 2010-03-08 19:54:11

+1

這不會編譯 - 「Dictionary 」所需的方法不是虛擬的。你將不得不作爲一個單獨的適配器來實現''IDictionary ''。 – 2012-11-20 12:43:21

0

鍵的字面意思是否需要爲NULL?收藏中的關鍵是一個索引。對於一個集合中的索引來說NULL沒有多大意義。

也許創建一個新類


public class ObjectEntry 
{ 
    public object objRef; 
    public string desc; 

    public ObjectEntry(object objectReference) 
    { 
     objRef = objectReference; 
     if (objRef = null) {desc = "Nothing";} 
     else {desc = objRef.Description;} //or whatever info you can get from a proper objRef value 
    } 
} 

newObj = new ObjectEntry(null); 
dict.add(newObj, newObj.desc); 
0

無需不同的實現Dicionary的。

在這裏我的答案請看: https://stackoverflow.com/a/22261282/212272

你也將能夠保持你的字典強類型:

var dict = new Dictionary<NullObject<int?>, string>(); 
dict[1] = "one int"; 
dict[null] = "null int"; 

Assert.AreEqual("one int", dict[1]); 
Assert.AreEqual("null int", dict[null]);