为什么Dictionary <tkey,tvalue =“”>没有IEnumerable <keyvaluepair <tkey,tvalue =“”>&gt;构造函数?</keyvaluepair <TKEY,> </TKEY,>

时间:2010-02-12 15:28:42

标签: .net generics

好的 - 所以我知道构建一个提供功能的工厂方法很简单;但鉴于Dictionary<TKey, TValue>IEnumerable<KeyValuePair<TKey, TValue>>,它不应该与Ctor相当,例如,List<T>的{​​{1}}?

它甚至更愚蠢,因为它提供了一个以ctor(IEnumerable<T> range)作为源的Ctor,但由于该接口也是IDictionary<TKey, TValue>,IEnumerable选项肯定会更有意义;除非在课程初次设计时IEnumerable<KeyValuePair<TKey, TValue>>界面不在身边。

情况更糟,因为如果你看一下ctor的IDictionary版本的实现 - 输入字典是用以下代码导入的:

IEnumerable<>

任何人都会想到为什么框架设计人员在需要基本界面时选择最具体的界面的理由很充分?

修改

@Mark Seeman建议避免由重复键引发异常 - 这可能接近事实 - 但请考虑这个例子:

foreach (KeyValuePair<TKey, TValue> pair in dictionary)
{
    this.Add(pair.Key, pair.Value);
}

我知道 - 测试是相反的 - 但出于某种原因,我认为这使我的观点更好:)

鉴于密钥比较器不是IDictionary接口的一部分,您可以永远保证您导入的字典不会生成重复密钥,因此[TestMethod] [ExpectedException(typeof(ArgumentException))] public void How_To_Break_The_IDictionary_Ctor_Design_Decision() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); dictionary.Add("hello", "world"); dictionary.Add("Hello", "world"); Dictionary<string, string> dictionary2 = new Dictionary<string, string>(dictionary, StringComparer.CurrentCultureIgnoreCase); } ,构建新的。

Ergo - 您可能只有一个IEnumerable构造函数可以执行相同的操作。

2 个答案:

答案 0 :(得分:13)

完全非官方猜测

如果构造函数允许IEnumerable<KeyValuePair<TKey, TValue>>,那么您将能够提供具有相同键的多个项目以及预期的行为是什么?

E.g。你可以做这样的事情:

var kvps = new[]
{
    new KeyValuePair<int, string>(1, "Foo"),
    new KeyValuePair<int, string>(1, "Bar"),
    new KeyValuePair<int, string>(1, "Baz")        
}
var dic = new Dictionary<int, string>(kvps);

你可以说这应该只是抛出一个异常以与Add方法的行为保持一致,但我猜想设计团队认为这将是一个更大的混乱来源而不是实际有用......

答案 1 :(得分:2)

  public static Dictionary<T, U> ToDictionary(
      this IEnumerable<KeyValuePair<T, U>> source)
  {
    return source.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
  }