Explicit felület implementálása (C# programozási útmutató)
Ha egy osztály két olyan illesztőt implementál, amelyek azonos aláírással rendelkező tagot tartalmaznak, akkor a tag az osztályon való implementálásával mindkét felület ezt a tagot fogja használni megvalósításként. Az alábbi példában az azonos metódus meghívására szolgáló Paint
összes hívás. Ez az első minta a következő típusokat határozza meg:
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");
}
}
A következő minta meghívja a metódusokat:
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
Előfordulhat azonban, hogy nem szeretné, hogy ugyanazt az implementációt mindkét interfészhez meghívja a rendszer. Ha más implementációt szeretne meghívni attól függően, hogy melyik felület van használatban, explicit módon implementálhat egy felülettagot. Az explicit felület implementálása olyan osztálytag, amelyet csak a megadott felületen keresztül hív meg. Nevezze el az osztálytagot az illesztő nevével és egy ponttal való előtagolásával. Példa:
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
Az osztálytag IControl.Paint
csak a IControl
felületen keresztül érhető el, és ISurface.Paint
csak a felületen keresztül ISurface
érhető el. Mindkét metódus implementációja különálló, és egyik sem érhető el közvetlenül az osztályon. Példa:
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
Az explicit implementáció olyan esetek megoldására is használható, amikor két interfész deklarálja az azonos nevű különböző tagokat, például egy tulajdonságot és egy metódust. Mindkét felület implementálásához az osztálynak explicit implementációt kell használnia a tulajdonsághoz P
vagy a metódushoz P
, vagy mindkettőhöz a fordítóhibák elkerülése érdekében. Példa:
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
Az explicit felület implementációja nem rendelkezik hozzáférés-módosítóval, mivel nem érhető el a definiált típus tagjaként. Ehelyett csak akkor érhető el, ha a felület egy példányán keresztül hívjuk meg. Ha hozzáférési módosítót ad meg egy explicit felület implementálásához, a CS0106 fordítóhiba jelenik meg. További információ: interface
(C# referencia).
Az illesztőben deklarált tagok implementációja definiálható. Ha egy osztály egy felületről örökli a metódus implementálását, az csak a felülettípus hivatkozásával érhető el. Az örökölt tag nem jelenik meg a nyilvános felület részeként. Az alábbi minta egy interfészmetódus alapértelmezett implementációit határozza meg:
public interface IControl
{
void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
// Paint() is inherited from IControl.
}
Az alábbi minta meghívja az alapértelmezett implementációt:
var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();
Az interfészt megvalósító IControl
bármely osztály felülbírálhatja az alapértelmezett Paint
metódust nyilvános metódusként vagy explicit felületi implementációként.