背景:
我们都非常熟悉标准Dictionary<TKey, TValue> 类型,以及它的属性,如果您尝试通过不存在的键访问元素,则会抛出KeyNotFoundException。
这对每个人都很熟悉,并且这种行为对于值字典来说是预期的。
最近,我分析了一个引发NullReferenceException的代码,从逻辑上讲,这是不可能的。
在调试之后,我发现了以下事情:一个人
在他的代码中使用了StringDictionary(顺便说一句,这很令人愉快,因为我知道有很多 .NET 程序员从未研究过System.Collections.Specialized)并且忘记了通过指定键检查字符串是否存在,因此字典静默返回null,稍后代码崩溃,因为null字典中应该不存在具有该值的行,并且不暗示对此的检查
在标准Dictionary和上述异常的创建的情况下,这个错误会更容易捕获,但是,它有一个StringDictionary稍微不同的“意识形态”,所以它通过一个不存在的键返回null(顺便说一下,不调用该方法与带有-值ContainsKey的指定键存在的字符串无法区分)null
实际上,问题本身:
为什么在设计的时候,他们StringDictionary脱离了大家熟悉的字典架构,而不是逻辑上抛出相应的异常,而是直接返回null?
在我看来,这样的决定应该有一些严肃的事实来支持。根据我的猜测:由于它是StringDictionary为快速(O(1))在字典中搜索字符串而创建的,也就是说,在这种情况下速度很关键,他们决定忽略抛出异常,因为这不是最快的操作)
但是,这只是我的猜猜,我想听听您的意见/查看有关此问题的链接)
简单得多 - Specialized 是前通用 .net 1.1 的遗迹。
Dictionary 的通用实现不能为不存在的值返回 null ——它必须同时使用引用类型和值类型,并且以相同的方式工作。为值类型返回 null 有点困难。
在引入泛型时,Specialized 中的类被大量使用,并且为了兼容性而保留了它们的行为。在现代项目中,使用 Specialized 的唯一原因是需要与遗留代码集成。
它们没有实现新的泛型接口,它们的行为奇怪且不可预测(例如
StringDictionary将键转换为小写),即使在基本操作上它们也可能比新泛型慢,例如: