【问题标题】:Why doesn't the C# Dictionary implement all of IDictionary?为什么 C# Dictionary 没有实现所有的 IDictionary?
【发布时间】:2011-08-26 21:15:36
【问题描述】:

我想创建一个类似字典的对象,并认为正确的方法是实现IDictionary<K,V> 接口,并使用组合来包含底层字典。我从下面开始(K=stringV=int

public class DictionaryLikeObject : IDictionary<string,int> {
  Dictionary<string,int> _backingDictionary = new Dictionary<string,int>();
}

然后我使用 Visual Studio 的“实现接口”功能将我需要的所有覆盖方法存根。

IDictionary的三个方法在Dictionary中好像不存在:

void Add(KeyValuePair<string, int> item);
void CopyTo(KeyValuePair<string, int>[] array, int arrayIndex);
bool Remove(KeyValuePair<string, int> item);

然而the Microsoft documentation 清楚地表明Dictionary 实现了IDictionary。所以我本来希望这三种方法可用。从文档中复制Dictionary&lt;K,V&gt;的定义

[SerializableAttribute]
[ComVisibleAttribute(false)]
public class Dictionary<K, V> : IDictionary<K, V>, 
ICollection<KeyValuePair<K, V>>, IEnumerable<KeyValuePair<K, V>>, 
IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback

我相信这三个缺失的方法可以在ICollection&lt;&gt; 中找到。但是Dictionary 确实有其他方法,例如Clear()

问题 1: 如果不实现这三个,C# 怎么能逃脱,为什么会这样?我怀疑这是编译器错误(出于我的原因,请参见下文)。 问题 2: 或者,我错过了什么?

这就是为什么我认为这可能是编译器错误。检查以下代码:

Dictionary<string, int> dictionary1 = new Dictionary<string, int>();
IDictionary<string, int> dictionary2 = new Dictionary<string, int>();
KeyValuePair<string, int> item = new KeyValuePair<string, int>("test", 1);
//dictionary1.Add(item); // compile error: No overload for method 'Add' takes 1 argument
dictionary2.Add(item); // works like a charm
Debug.WriteLine(@"dictionary2[""test""] = {0}", dictionary2["test"]); // outputs: dictionary2["test"] = 1

方法void Add(KeyValuePair&lt;string, int&gt; item) 似乎不在Dictionary&lt;string,int&gt; 中(因为它不编译),但它在IDictionary&lt;string,int&gt; 中,并且编译器确实找到了它的实现。 问题 3:这是怎么回事?

请注意,Dictionary&lt;K,V&gt; 的 Microsoft 文档未指定这三种方法。

最后,在我的实际实现中,我最终使用了

IDictionary<string,int> _backingDictionary = new Dictionary<string,int>();

而不是

Dictionary<string,int> _backingDictionary = new Dictionary<string,int>();

这样所有三种方法都可以轻松工作。

【问题讨论】:

    标签: c# dictionary idictionary


    【解决方案1】:

    Dictionary&lt;TKey, TValue&gt; 确实实现了这些方法,它只是明确地这样做。因此,您必须通过IDictionary&lt;TKey, TValue&gt; 接口访问它。

    Dictionary<string, string> map = ...;
    KeyValuePair<string, string> pair = ...;
    map.Add(pair);  // Compilation Error
    ((IDictionary<string, string>)map).Add(pair);  // Works
    

    显式实现通过在定义点精确指定实例方法实现的接口方法来工作。例如

    interface IFoo {
      void Method(); 
    }
    
    class C1 : IFoo {
      // Implicitly implements IFoo.Method
      public void Method() { }
    }
    
    class C2 : IFoo {
      // Explicitly implements IFoo.Method
      void IFoo.Method() { }
    }
    

    【讨论】:

    • 这正是我的第一个猜测。你知道为什么 MSDN 文档中没有指定这个吗?另外,他们为什么要隐藏这些方法?
    • @the_drow,我不确定他们为什么不在文档中做出这种区分,我也不能 100% 确定他们为什么做出选择。我对后者的第一直觉是他们希望默认提供一个 Add 重载。
    • @the_drow:实际上是在 MSDN 文档中指定的。您只需向下滚动到“显式接口实现”
    • 因此,显式/隐式答案明确了这个问题。 JaredPar 的回答,再加上仔细阅读 Microsoft 的显式/隐式实现文档 link 和 StackOverflow 线程 link,确实很有帮助。另外,感谢 Daniel 指出 MSDN 文档确实列出了“显式实现”。
    猜你喜欢
    • 1970-01-01
    • 2011-10-07
    • 2021-02-19
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2012-04-29
    相关资源
    最近更新 更多