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

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

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

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, что означает практически любой ADO.NET-совместимый поставщик данных.

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

interface IThermometer
{
    double CurrentTemperature { get; }
}

Теперь у нас есть способ получить температуру, хотя нам все равно, как именно она измеряется. Мы можем создать различные реализации:

class MercuryThermometer : IThermometer
{
    public double CurrentTemperature
    {
        get { return ... /* gets the temperature somehow */ }
    }
}

Остальной программе не нужно знать, какой термометр она использует.

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

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

Другие вопросы по тегам