Назначение интерфейса IDictionary


В чем заключается необходимость IDictionary интерфейса. Как можно инициализировать интерфейс IDictionary. В конце концов, это всего лишь интерфейс. Следующий фрагмент кода взят из msdn. Я не мог этого понять.

IDictionary<string, string> openWith = new Dictionary<string, string>();
5 3

5 ответов:

Он определяет важные функции , которые должен реализовать словарь.

Строка из MSDN означает, что вы создаете объект openWith, который реализует функции (методы), определенные в интерфейсе IDictionary.

При использовании словаря для объявления переменной типа:

Dictionary<string,string> openWith=.....;

Вы связываетесь с конкретным типом объекта. Но когда вы используете

IDictionary<string,string> openWith=....;

Вы можете использовать его с любым объектом, который реализует IDictionary интерфейс, возможно, ваш собственный пользовательский класс:)

Весь смысл интерфейсов заключается в обеспечении... ну, интерфейс к любому модулю (я использую здесь "модуль" в широком смысле), так что вызывающему коду не придется беспокоиться о том, как этот конкретный интерфейс реализован.

Что касается "как можно инициализировать интерфейс IDictionary", то это технически неверно. То, что может быть инициализировано, - это переменная, тип которой IDictionary<T, V>. Конечно, переменные должны быть инициализированы, но это обычно скрыто от "клиентского кода".

IDictionary есть впрочем, не очень представительно. Вместо этого рассмотрим интерфейс IDataReader. Вы наверняка имели дело с ADO.NET, так что это должно выглядеть знакомо:

public Foo PopulateFromDataReader(SqlDataReader dataReader)
Этот конкретный метод тесно связан с SqlDataReader, поэтому вам придется переписать его, чтобы он поддерживал, скажем, Access или Oracle, или MySQL, или Firebird, или что-то еще. Другими словами, вы зависите от реализации.

Теперь рассмотрим:

public Foo PopulateFromDataReader(IDataReader dataReader)

Этот метод может быть использован с любым классом, который реализует IDataReader, что означает в основном с любым АДО.Net-совместимых поставщика данных.

Он ничем не отличается от любого другого интерфейса. Попробуйте подумать о более простом примере:

interface IThermometer
{
    double CurrentTemperature { get; }
}
Теперь у нас есть способ получить температуру, хотя нам все равно, как именно она измеряется. Мы можем создавать различные реализации:
class MercuryThermometer : IThermometer
{
    public double CurrentTemperature
    {
        get { return ... /* gets the temperature somehow */ }
    }
}
Остальная часть программы не должна знать, какой термометр она использует.

Я подозреваю, что вы просто упустили из виду разницу между переменной, типизированной как IDictionary<,> (интерфейс), и значением (ссылка), инициализированным как Dictionary<,> (Примечание нет I; конкретный тип).

Это также полезно для модульного тестирования. Вы можете написать модульный тест для метода, который принимает IDictionary вместо словаря,и передать макет. Если бы он принял экземпляр класса (который также может быть запечатан), вы были бы немного завинчены (вам пришлось бы использовать шаблон адаптера и т. д.).