Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Если класс реализует два интерфейса, которые содержат член с одной и той же сигнатурой, то реализация этого члена в классе приведет к использованию обоих интерфейсов в качестве их реализации. В следующем примере все вызовы Paint
используют один и тот же метод. Этот первый пример определяет типы:
public interface IControl
{
void Paint();
}
public interface ISurface
{
void Paint();
}
public class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
Console.WriteLine("Paint method in SampleClass");
}
}
Следующий пример вызывает методы:
SampleClass sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;
// The following lines all call the same method.
sample.Paint();
control.Paint();
surface.Paint();
// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass
Но для обоих интерфейсов может потребоваться не использовать одну и ту же реализацию. Чтобы вызвать другую реализацию в зависимости от используемого интерфейса, можно явно реализовать член интерфейса. Явная реализация интерфейса — это член класса, который вызывается только через указанный интерфейс. Назовите член класса, префиксируя его именем интерфейса и периодом. Рассмотрим пример.
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
Член IControl.Paint
класса доступен только через IControl
интерфейс и ISurface.Paint
доступен только через ISurface
интерфейс. Обе реализации метода независимы, и ни одна из них не доступна напрямую в классе. Рассмотрим пример.
SampleClass sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;
// The following lines all call the same method.
//sample.Paint(); // Compiler error.
control.Paint(); // Calls IControl.Paint on SampleClass.
surface.Paint(); // Calls ISurface.Paint on SampleClass.
// Output:
// IControl.Paint
// ISurface.Paint
Явная реализация также используется для устранения случаев, когда два интерфейса объявляют разные члены одного и того же имени, например свойство и метод. Для реализации обоих интерфейсов класс должен использовать явную реализацию для свойства P
или метода P
или обоих, чтобы избежать ошибки компилятора. Рассмотрим пример.
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
У явной реализации интерфейса нет модификатора доступа, так как он недоступен в качестве члена типа, в который он определен. Вместо этого он доступен только при вызове через экземпляр интерфейса. При указании модификатора доступа для явной реализации интерфейса возникает ошибка компилятора CS0106. Дополнительные сведения см. в разделе interface
(Справочник по C#).
Вы можете определить реализацию для членов, объявленных в интерфейсе. Если класс наследует реализацию метода из интерфейса, этот метод доступен только через ссылку типа интерфейса. Унаследованный элемент не отображается как часть общедоступного интерфейса. В следующем примере определяется реализация по умолчанию для метода интерфейса:
public interface IControl
{
void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
// Paint() is inherited from IControl.
}
Следующий пример вызывает реализацию по умолчанию:
var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();
Любой класс, реализующий IControl
интерфейс, может переопределить метод по умолчанию либо как открытый метод, либо как явную реализацию Paint
интерфейса.