C# – 需要一个允许空键的IDictionary实现

基本上,我想要这样的东西:

Dictionary dict = new Dictionary(); dict.Add(null, "Nothing"); dict.Add(1, "One"); 

是否有任何内置到基类库中允许这样做? 添加null键时,上面的代码将在运行时抛出exception。

谢谢

您可以避免使用null并创建一个执行相同操作的特殊单例值类。 例如:

 public sealed class Nothing { public static readonly Nothing Value = new Nothing(); private Nothing() {} } Dictionary dict = new Dictionary(); dict.add(Nothing.Value, "Nothing"); dict.add(1, "One"); 

如果您打算使您的集合更强类型,则此方法将无法工作 – 例如,您希望密钥是字符串。 由于字符串是密封的,因此您无法从中inheritance以创建“特殊值”替代null。 你的选择变得有点复杂。 你可以:

  1. 创建一些特殊的常量值来表示“空”/“空”的情况。 一种hacky,绝对是一个混乱的道路。 如果字典对于某些实现类是完全私有的,并且您可以编写一些Encode / Decode实用程序方法以避免传播有关如何在整个位置转换键的知识,这可能是一种可行的方法。
  2. 创建自己的IDictionary实现,内部委托给Dictionary <>实例 – 除了null的情况。 这违反了对IDictionary <>接口的记录期望,它确实说空键应该抛出exception。 但如果这是解决您真正问题的唯一方法,那么您可以逃脱它。 这仅在您拥有并创建字典实例时有效。
  3. 找到一种方法来解决您的问题,而无需在字典中存储“null”键。 例如,考虑不在字典中填充null键并使用一些特殊的案例逻辑来处理它。 密钥必须是可清除的并且与底层实现相当,这就是为什么通常禁止null。

顺便说一句,你的字典键真的需要关键是object吗? 这可能会导致细微的错误,因为使用了引用相等性,您可能希望将Equals()作为比较的基础进行评估。

这个怎么样?

 public class NullableDictionnary : Dictionary { 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; } } } } 

NameValueCollection可以采用null键,但它不实现IDictionary。 然而,很容易从DictionaryBase派生并提供添加/删除/索引器等,只需将null替换为内置的内容,如:

 class MyDictionary : DictionaryBase { private readonly object nullKey = new object(); void Add(object key, string value) { if ( key == null ) { key = nullKey; } .. call base methods } } 

密钥字面上是否需要为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); 

不需要不同的Dicionary实现。

看看我的答案: https : //stackoverflow.com/a/22261282/212272

您还可以保持字典强类型:

 var dict = new Dictionary, string>(); dict[1] = "one int"; dict[null] = "null int"; Assert.AreEqual("one int", dict[1]); Assert.AreEqual("null int", dict[null]);