Explicit gränssnittsimplementering (C#-programmeringsguide)
Om en klass implementerar två gränssnitt som innehåller en medlem med samma signatur kommer implementeringen av den medlemmen i klassen att leda till att båda gränssnitten använder den medlemmen som implementering. I följande exempel anropar alla anrop för att Paint
anropa samma metod. Det här första exemplet definierar typerna:
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");
}
}
Följande exempel anropar metoderna:
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
Men du kanske inte vill att samma implementering ska anropas för båda gränssnitten. Om du vill anropa en annan implementering beroende på vilket gränssnitt som används kan du implementera en gränssnittsmedlem explicit. En explicit gränssnittsimplementering är en klassmedlem som endast anropas via det angivna gränssnittet. Namnge klassmedlemmen genom att prefixera den med namnet på gränssnittet och en punkt. Till exempel:
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
Klassmedlemmen IControl.Paint
är endast tillgänglig via IControl
gränssnittet och ISurface.Paint
är endast tillgänglig via ISurface
. Båda metodimplementeringarna är separata och ingen av dem är tillgängliga direkt i klassen. Till exempel:
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
Explicit implementering används också för att lösa fall där två gränssnitt var och en deklarerar olika medlemmar med samma namn, till exempel en egenskap och en metod. För att implementera båda gränssnitten måste en klass använda explicit implementering antingen för egenskapen P
, eller metoden P
, eller båda, för att undvika ett kompilatorfel. Till exempel:
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
En explicit gränssnittsimplementering har ingen åtkomstmodifierare eftersom den inte är tillgänglig som medlem av den typ som den definieras i. I stället är den endast tillgänglig när den anropas via en instans av gränssnittet. Om du anger en åtkomstmodifierare för en explicit gränssnittsimplementering får du kompilatorfelet CS0106. Mer information finns i interface
(C#-referens).
Du kan definiera en implementering för medlemmar som deklarerats i ett gränssnitt. Om en klass ärver en metodimplementering från ett gränssnitt är den metoden endast tillgänglig via en referens av gränssnittstypen. Den ärvda medlemmen visas inte som en del av det offentliga gränssnittet. Följande exempel definierar en standardimplementering för en gränssnittsmetod:
public interface IControl
{
void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
// Paint() is inherited from IControl.
}
Följande exempel anropar standardimplementeringen:
var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();
Alla klasser som implementerar IControl
gränssnittet kan åsidosätta standardmetoden Paint
, antingen som en offentlig metod eller som en explicit gränssnittsimplementering.