dev*_*xer 67 .net c# dictionary hashtable
显然,null
即使您的密钥是可空类型,也不能使用密钥.
这段代码:
var nullableBoolLabels = new System.Collections.Generic.Dictionary<bool?, string>
{
{ true, "Yes" },
{ false, "No" },
{ null, "(n/a)" }
};
Run Code Online (Sandbox Code Playgroud)
...导致此异常:
值不能为空.参数名称:key
描述:执行当前Web请求期间发生未处理的异常.请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息.
[ArgumentNullException: Value cannot be null. Parameter name: key]
System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) +44
System.Collections.Generic.Dictionary'2.Insert(TKey key, TValue value, Boolean add) +40
System.Collections.Generic.Dictionary'2.Add(TKey key, TValue value) +13
为什么.NET框架允许键的可空类型,但不允许空值?
Dyn*_*ard 36
它会告诉你同样的事情,如果你有一个Dictionary<SomeType, string>
,SomeType
作为一个引用类型,并且你试图传递null
作为键,它不是只影响可空类型的东西bool?
.您可以使用任何类型作为键,可以为空或者为空.
这一切都归结为你无法真正比较的事实nulls
.我假设背后的逻辑不能放入null
密钥,一个旨在与其他对象进行比较的属性是它使得比较null
引用的语法不连贯.
如果你想从规范中得到一个理由,它归结为MSDN上的"A key不能是空引用" .
如果你想要一个可能的解决方法的例子,你可以尝试类似于需要一个允许空键的IDictionary实现
Mah*_*dsi 14
通常,您必须回到C++方法和技术,以完全理解.NET Framework以特定方式工作的方式和原因.
在C++中,您经常需要选择一个不会被使用的键 - 字典使用此键指向已删除和/或空的条目.例如,您有一个字典<int, int>
,在插入条目后,您将其删除.而不是当时和那里运行垃圾清理,重组字典,并导致糟糕的表现; 字典将只用你之前选择的键替换KEY值,基本上意思是"当你遍历字典memoryspace时,假装这<key,value>
对不存在,可以随意覆盖它."
这样的密钥也用于以特定方式在桶中预分配空间的字典 - 您需要一个键来"初始化"桶,而不是为每个条目指定一个标志,指示其内容是否有效.所以不是有一个三元<key, value, initialized>
组<key, value>
,你会得到一个规则的元组,如果key == empty_key那么它还没有被初始化 - 因此你可能不会使用empty_key作为有效的KEY值.
您可以在此处的文档中的Google哈希表(适用于.NET的人员:)中查看此类行为:http://google-sparsehash.googlecode.com/svn/trunk/doc/dense_hash_map.html
看看set_deleted_key
和set_empty_key
函数来得到我正在谈论的内容.
我打赌.NET使用NULL作为唯一的deleted_key或empty_key,以便做这些提高性能的漂亮技巧.