为什么Dictionary没有AddRange? [英] Why doesn't Dictionary have AddRange?

查看:409
本文介绍了为什么Dictionary没有AddRange?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题是基本的,为什么我不能:

 字典< string,string> dic = new Dictionary< string,string>(); 
dic.AddRange(MethodThatReturnAnotherDic());


解决方案

对原始问题的评论总结得很好:


因为没有人设计,指定,实施,测试,记录和发送该功能。 - @Gabe Moothart


至于为什么?那么可能是因为合并词典的行为不能以符合框架指南的方式推理。



AddRange 不存在,因为范围对关联容器没有任何意义,因为数据范围允许重复条目。例如,如果您有一个 IEnumerable< KeyValuePair< K,T> 该集合不会防止重复条目。



添加键值对的集合甚至合并两个字典的行为是直截了当的。然而,如何处理多个重复条目的行为不是。



当处理重复时,该方法的行为应该是什么? / strong>



至少有三种解决方案可以考虑:


    第一个条目的异常
  1. 抛出包含所有重复条目的例外

  2. 忽略重复

抛出异常时,原始字典的状态应该是什么?



添加几乎总是作为原子操作实现:它成功并更新集合的状态,否则失败,并且收集的状态保持不变。由于 AddRange 可能由于重复错误而失败,使其行为与添加保持一致的方式也将使其原子通过在任何副本上抛出异常,并将原始字典的状态保持不变。



作为API消费者,必须迭代删除重复元素,这意味着 AddRange 应该抛出一个包含所有重复值的异常。



然后选择:


  1. 抛出所有重复的异常,将原始字典单独留下。

  2. 忽略重复并继续。

有两个用于支持这两种用例的参数。为此,您是否向签名添加了一个 IgnoreDuplicates 标志?



IgnoreDuplicates 标志(设置为true时)也将提供显着的加速,因为底层实现绕过代码进行重复检查。



所以现在,你有一个标志,允许 AddRange 支持这两种情况,但具有无效的副作用(这是框架设计师非常难以避免的)。



摘要



由于在处理重复项时没有明确,一致和预期的行为,所以一起处理它们并不容易,而不是提供开始的方法。 >

如果您发现自己不断需要合并字典,您当然可以编写自己的扩展方法来合并字典,这样可以以适用于您的应用程序的方式运行。


Title is basic enough, why can't I:

Dictionary<string, string> dic = new Dictionary<string, string>();
dic.AddRange(MethodThatReturnAnotherDic());

解决方案

A comment to the original question sums this up pretty well:

because no one ever designed, specified, implemented, tested, documented and shipped that feature. - @Gabe Moothart

As to why? Well, likely because the behavior of merging dictionaries can't be reasoned about in a manner that fits with the Framework guidelines.

AddRange doesn't exist because a range doesn't have any meaning to an associative container, as the range of data allows for duplicate entries. E.g if you had an IEnumerable<KeyValuePair<K,T>> that collection does not guard against duplicate entries.

The behavior of adding a collection of key-value pairs, or even merging two dictionaries is straight-forward. The behavior of how to deal with multiple duplicate entries, however, is not.

What should be the behavior of the method when it deals with a duplicate?

There are at least three solutions I can think of:

  1. throw an exception for the first entry that is a duplicate
  2. throw an exception that contains all the duplicate entries
  3. Ignore duplicates

When an exception is thrown, what should be the state of the original dictionary?

Add is almost always implemented as an atomic operation: it succeeds and updates the state of the collection, or it fails, and the state of the collection is left unchanged. As AddRange can fail due to duplicate errors, the way to keep its behavior consistent with Add would be to also make it atomic by throwing an exception on any duplicate, and leave the state of the original dictionary as unchanged.

As an API consumer, it would be tedious to have to iteratively remove duplicate elements, which implies that the AddRange should throw a single exception that contains all the duplicate values.

The choice then boils down to:

  1. Throw an exception with all duplicates, leaving the original dictionary alone.
  2. Ignore duplicates and proceed.

There are arguments for supporting both use cases. To do that, do you add a IgnoreDuplicates flag to the signature?

The IgnoreDuplicates flag (when set to true) would also provide a significant speed up, as the underlying implementation would bypass the code for duplicate checking.

So now, you have a flag that allows the AddRange to support both cases, but has an undocumented side effect (which is something that the Framework designers worked really hard to avoid).

Summary

As there is no clear, consistent and expected behavior when it comes to dealing with duplicates, it's easier to not deal with them all together, and not provide the method to begin with.

If you find yourself continually having to merge dictionaries, you can of course write your own extension method to merge dictionaries, which will behave in a manner that works for your application(s).

这篇关于为什么Dictionary没有AddRange?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆