27

私はディクショナリのようなオブジェクトを作成したいと考えていましたが、IDictionary<K,V>インターフェイスを実装し、コンポジションを使用して基礎となるディクショナリを含めることが正しい方法だと考えました。私は以下から始めました ( K= string, V= int)

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

次に、Visual Studio の「Implement Interface」機能を使用して、必要なすべてのカバー メソッドをスタブ化しました。

IDictionaryには存在しないように見えるの 3 つの方法Dictionary:

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

それでも、Microsoft のドキュメントDictionaryは、それが実装していることを明確に示していますIDictionary。したがって、これら 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()しかし、そのような他の方法もそうDictionaryです。

質問 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:何が起こっているのですか?

Microsoft のドキュメントでDictionary<K,V>は、これら 3 つの方法が指定されていないことに注意してください。

最後に、実際の実装では、最終的に使用しました

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

それ以外の

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

3つの方法すべてが簡単に機能するように。

4

1 に答える 1

46

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() { }
}
于 2011-08-26T21:17:23.110 に答える