标题已经够基本的了,为什么我不能:
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.AddRange(MethodThatReturnAnotherDic());
标题已经够基本的了,为什么我不能:
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.AddRange(MethodThatReturnAnotherDic());
对原始问题的 comments 很好地总结了这一点:
因为从来没有人设计、指定、实施、测试、记录和发布过该功能.-@加布·穆萨特
至于为什么呢?嗯,很可能是因为合并字典的行为不能以一种符合框架指导方针的方式进行推理.
AddRange
不存在,因为范围对于关联容器没有任何意义,因为数据范围允许重复条目.例如,如果您有IEnumerable<KeyValuePair<K,T>>
,则该集合不会防止重复条目.
添加一组键值对,甚至合并两个字典的行为都是直截了当的.然而,如何处理多个重复条目的行为并不重要.
What should be the behavior of the method when it deals with a duplicate?个
我能想到的解决方案至少有三种:
When an exception is thrown, what should be the state of the original dictionary?
Add
几乎总是作为一个原子操作实现的:它成功并更新集合的状态,或者失败,集合的状态保持不变.由于AddRange
可能会因重复错误而失败,因此保持其行为与Add
一致的方法是,通过对任何重复项抛出异常,使其成为原子,并保持原始字典的状态不变.
作为API使用者,必须迭代删除重复的元素是很乏味的,这意味着AddRange
应该抛出一个包含all个重复值的异常.
然后, Select 归结为:
这两种用例都有支持的理由.要做到这一点,你要在签名上加一面IgnoreDuplicates
的旗帜吗?
IgnoreDuplicates
标志(设置为true时)也将提供显著的速度提升,因为底层实现将绕过代码进行重复判断.
现在,你有了一个标志,允许AddRange
支持这两种情况,但有一个未记录的副作用(这是框架设计师非常努力避免的).
Summary
由于在处理重复项时没有明确、一致和预期的行为,因此更容易不同时处理它们,也不提供开始的方法.
如果您发现自己必须不断地合并字典,那么您当然可以编写自己的扩展方法来合并字典,其行为方式将适用于您的应用程序.