基本上,我想要这样的东西:
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.Add(null, "Nothing");
dict.Add(1, "One");
基类库中是否有允许这样做的内容?添加空键时,上面的代码将在运行时抛出异常。
由于
答案 0 :(得分:11)
您可以避免使用null并创建一个执行相同操作的特殊单例值类。例如:
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。你的选择变得有点复杂。你可以:
顺便说一下,你的词典密钥真的需要密钥object
吗?这可能会导致细微的错误,因为您可能希望将Equals()作为比较的基础来使用引用相等。
答案 1 :(得分: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; }
}
}
}
答案 2 :(得分:2)
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
}
}
答案 3 :(得分: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);
答案 4 :(得分: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]);
答案 5 :(得分:0)
jestro的答案略有不同,以寻求更清洁的解决方案(对我而言),从而使您更清楚地了解您要做什么。显然,这可以根据需要扩展。但是,您得到图片后,只需包装一下即可。
public class NullDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
private TValue _default;
public new TValue this[TKey key]
{
get {
if(key == null)
{
return _default;
}
return _decorated[key];
}
}
private Dictionary<TKey, TValue> _decorated;
public NullDictionary( Dictionary<TKey,TValue> decorate, TValue defaultValue = default)
{
_decorated = decorate;
_default = defaultValue;
}
}