Назначение интерфейса 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 вместо словаря и передает макет. Если бы он принял экземпляр класса (который также мог бы быть запечатан), вы бы немного облажались (вам пришлось бы использовать шаблон адаптера и так далее).