Явные реализации членов интерфейса

Для целей реализации интерфейсов в классе или структуре могут объявляться явные реализации членов интерфейса. Явная реализация члена интерфейса представляет собой объявление метода, свойства, события или индекса, содержащее ссылку на полное имя члена интерфейса. Пример

interface IList
{
T[] GetElements();
}

interface IDictionary
{
V this[K key];

void Add(K key, V value);
}

class List: IList, IDictionary
{
T[] IList.GetElements() {...}

T IDictionary.this[int index] {...}

void IDictionary.Add(int index, T value) {...}
}

В этом примере строки IDictionary.this и IDictionary.Add являются явными реализациями членов интерфейса.

В некоторых случаях имя члена интерфейса может быть неподходящим для реализующего класса. В этом случае член интерфейса может быть реализован с использованием явной реализации члена интерфейса. Например, в классе, который реализует абстракцию файла, скорее всего будет реализована функция-член Close, в результате выполнения этой функции высвобождается файловый ресурс и реализуется метод Dispose интерфейса IDisposable с использованием явной реализации члена интерфейса:

interface IDisposable
{
void Dispose();
}

class MyFile: IDisposable
{
void IDisposable.Dispose() {
Close();
}

public void Close() {
// Do what's necessary to close the file
System.GC.SuppressFinalize(this);
}
}

Получить доступ к явной реализации члена интерфейса с использованием его полного имени в вызванном методе, обращении к свойству или индексатору невозможно. Доступ к явной реализации члена интерфейса можно получить только через экземпляр интерфейса, в этом случае обращение к нему следует выполнять просто по имени его члена.

Включение в явную реализацию члена интерфейса модификаторов доступа, а также модификаторов abstract, virtual, override и static приведет к ошибке при компилировании.

Характеристики уровня доступа в явных реализациях члена интерфейса отличаются от таких характеристик других членов. Поскольку доступ к явным реализациям члена интерфейса по полному имени при вызове метода или при обращении к свойству невозможен, они в некотором роде являются закрытыми. Тем не менее, так как можно получить доступ к ним через экземпляр интерфейса, они также в некотором роде являются открытыми.

Явные реализации члена интерфейса служат двум основным целям:

· Поскольку к явным реализациям члена интерфейса нельзя получить доступ через экземпляры классов или структур, они позволяют исключить реализации интерфейса из открытого интерфейса класса или структуры. Это особенно полезно в том случае, если в классе или структуре реализуется внутренний интерфейс, который не предоставляет интереса для объекта, где используется этот класс или эта структура .



· Явные реализации члена интерфейса позволяют разрешить неоднозначности членов интерфейса с одинаковой подписью. Без явных реализаций члена интерфейса было бы невозможно иметь разные реализации члена интерфейса с одинаковыми подписью и типом возвращаемого значения, а также было бы невозможно включить в класс или структуру любые реализации членов интерфейса с одинаковой подписью и разными типами возвращаемых значений.

Явная реализация члена интерфейса является допустимой только в том случае, если в списке базовых классов класса или структуры содержится интерфейс, содержащий член, у которого полное имя, тип и типы параметров полностью совпадают с соответствующими данными явной реализации члена интерфейса. Так, в следующем классе

class Shape: ICloneable
{
object ICloneable.Clone() {...}

int IComparable.CompareTo(object other) {...} // invalid
}

объявление метода IComparable.CompareTo приведет к ошибке времени компиляции, поскольку интерфейс IComparable не включен в список базовых классов класса Shape и не является базовым интерфейсом для интерфейса ICloneable. Аналогичным образом в объявлениях

class Shape: ICloneable
{
object ICloneable.Clone() {...}
}

class Ellipse: Shape
{
object ICloneable.Clone() {...} // invalid
}

объявление метода ICloneable.Clone в классе Ellipse приведет к ошибке времени компиляции, поскольку интерфейс ICloneable не указан явно в списке базовых классов класса Ellipse.

Полное имя интерфейса должно указывать интерфейс, в котором был объявлен этот член. Так, в объявлениях

interface IControl
{
void Paint();
}

interface ITextBox: IControl
{
void SetText(string text);
}

class TextBox: ITextBox
{
void IControl.Paint() {...}

void ITextBox.SetText(string text) {...}
}

явная реализация члена интерфейса Paint должна быть записана в форме IControl.Paint.


yazik-gipertekstovoj-razmetki-html.html
yazik-hudozhestvennih-tekstov.html
    PR.RU™