logo
CSharp_Prog_Guide

Явная реализация интерфейса33

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

interface IControl

{

void Paint();

}

interface ISurface

{

void Paint();

}

class SampleClass : IControl, ISurface

{

// Both ISurface.Paint and IControl.Paint call this method.

public void Paint()

{

}

}

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

----

The class member IControl.Paint is only available through the IControl interface, and ISurface.Paint is only available through ISurface. Both method implementations are separate, and neither is available directly on the class. For example:

SampleClass obj = new SampleClass();

//obj.Paint(); // Compiler error.

IControl c = (IControl)obj;

c.Paint(); // Calls IControl.Paint on SampleClass.

ISurface s = (ISurface)obj;

s.Paint(); // Calls ISurface.Paint on SampleClass.

Explicit implementation is also used to resolve cases where two interfaces each declare different members of the same name such as a property and a method:

interface ILeft

{

int P { get;}

}

interface IRight

{

int P();

}

To implement both interfaces, a class has to use explicit implementation either for the property P, or the method P, or both, to avoid a compiler error. For example:

class Middle : ILeft, IRight

{

public int P() { return 0; }

int ILeft.P { get { return 0; } }

}

Член класса IControl.Paint доступен только через интерфейс IControl, а член ISurface.Paint — только через интерфейс ISurface. Каждая реализация метода является независимой и недоступна в классе напрямую. Пример.

SampleClass obj = new SampleClass();

//obj.Paint(); // Compiler error.

IControl c = (IControl)obj;

c.Paint(); // Calls IControl.Paint on SampleClass.

ISurface s = (ISurface)obj;

s.Paint(); // Calls ISurface.Paint on SampleClass.

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

interface ILeft

{

int P { get;}

}

interface IRight

{

int P();

}

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

--

How to: Explicitly Implement Interface Members

This example declares an interface, IDimensions, and a class, Box, which explicitly implements the interface members getLength and getWidth. The members are accessed through the interface instance dimensions.

Example

interface IDimensions

{

float getLength();

float getWidth();

}

class Box : IDimensions

{

float lengthInches;

float widthInches;

Box(float length, float width)

{

lengthInches = length;

widthInches = width;

}

// Explicit interface member implementation:

float IDimensions.getLength()

{

return lengthInches;

}

// Explicit interface member implementation:

float IDimensions.getWidth()

{

return widthInches;

}

static void Main()

{

// Declare a class instance box1:

Box box1 = new Box(30.0f, 20.0f);

// Declare an interface instance dimensions:

IDimensions dimensions = (IDimensions)box1;

// The following commented lines would produce compilation

// errors because they try to access an explicitly implemented

// interface member from a class instance:

//System.Console.WriteLine("Length: {0}", box1.getlength());

//System.Console.WriteLine("Width: {0}", box1.getwidth());

// Print out the dimensions of the box by calling the methods

// from an instance of the interface:

System.Console.WriteLine("Length: {0}", dimensions.getLength());

System.Console.WriteLine("Width: {0}", dimensions.getWidth());

}

}

Length: 30

Width: 20