2011-08-26 16 views
25

辞書のようなオブジェクトを作成したかったので、IDictionary<K,V>インターフェイスを実装するのが正しい方法だと思って、基本の辞書を組み込むために合成を使用してください。私はその後、私は私が必要となるすべてのカバーメソッドをスタブアウトするには、Visual Studioの「インタフェースを実装する」能力を使用し、以下の(K = string、= intVなぜC#ディクショナリはすべてIDictionaryを実装していませんか?

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

から始まりました。 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明確DictionaryIDictionaryを実装していることを示しています。だから私はこれら3つの方法が利用可能であると期待していたでしょう。 、ドキュメントからDictionary<K,V>

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

これら3つの不足しているメソッドの定義をコピーするには、私は信じて、ICollection<>で発見されています。しかしが持っているClear()のような他の方法もあります。

質問1: C#はどのようにこれらの3つを実装せずに立ち去ることができますか?これはなぜですか?私はこれがコンパイラエラーだと思う(私の推論のため、以下を参照)。 質問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<string, int> item)は、(それがコンパイルされませんので)Dictionary<string,int>でないと表示されますが、それはIDictionary<string,int>であり、そして何とかコンパイラが正しくの実装を見つけるん:次のコードを調べます。 質問3:何が起こっているのですか?

Dictionary<K,V>のMicrosoftドキュメントでは、これら3つの方法を指定していないことに注意してください。すべての3つの方法が簡単に仕事ができるように

最後には、私の実際の実装では、私が

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

代わりの

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

を使用して終了しました。

答えて

44

Dictionary<TKey, TValue>は、これらのメソッドを実装しています。したがって、IDictionary<TKey, TValue>インターフェイス経由でアクセスする必要があります。

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() { } 
} 
+1

これはまさに私の最初の推測でした。なぜこれがMSDNのドキュメントで指定されていないのか知っていますか?また、なぜそれらの方法を隠してしまったのですか? –

+0

@the_drow、私は彼らがなぜドキュメンテーションでその区別をしないのか分からないし、なぜ彼らが選んだのか100%確信していない。後者のための私の最初の本能は、デフォルトでAddの単一のオーバーロードを提供したかったということです。 – JaredPar

+6

@the_drow:実際にはMSDNのドキュメントで指定されています。 Explicit Interface Implementationにスクロールしてください。 – Daniel

関連する問題