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
如果您打算使您的集合更强类型,则此方法将无法工作 – 例如,您希望密钥是字符串。 由于字符串是密封的,因此您无法从中inheritance以创建“特殊值”替代null。 你的选择变得有点复杂。 你可以:
- 创建一些特殊的常量值来表示“空”/“空”的情况。 一种hacky,绝对是一个混乱的道路。 如果字典对于某些实现类是完全私有的,并且您可以编写一些Encode / Decode实用程序方法以避免传播有关如何在整个位置转换键的知识,这可能是一种可行的方法。
- 创建自己的IDictionary实现,内部委托给Dictionary <>实例 – 除了null的情况。 这违反了对IDictionary <>接口的记录期望,它确实说空键应该抛出exception。 但如果这是解决您真正问题的唯一方法,那么您可以逃脱它。 这仅在您拥有并创建字典实例时有效。
- 找到一种方法来解决您的问题,而无需在字典中存储“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]);