Подтвердить что ты не робот

Почему Словарь С# не реализует все IDictionary?

Я хотел создать похожий на словарь объект и думал, что правильным способом было бы реализовать интерфейс IDictionary<K,V> и использовать композицию для включения базового словаря. Я начал с ниже (K= string, V= 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);

Тем не менее документация Microsoft четко указывает, что Dictionary реализует IDictionary. Поэтому я ожидал, что эти три метода будут доступны. Чтобы скопировать из документации, определение 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

Эти три отсутствующих метода, я считаю, находятся в ICollection<>. Но существуют и другие методы, такие как Clear(), что Dictionary.

Вопрос 1: Как С# может уйти, не выполняя эти три, и почему это так? Я подозреваю, что это ошибка компилятора (для моих рассуждений, см. Ниже). Вопрос 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> не указаны эти три метода.

Наконец, в моей реальной реализации я закончил использование

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

вместо

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

чтобы все три метода могли легко работать.

4b9b3361

Ответ 1

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