Implémentation d’interface explicite (Guide de programmation C#)

Si une classe implémente deux interfaces qui contiennent un membre avec la même signature, l’implémentation de ce membre sur la classe a pour conséquence que les deux interfaces utilisent ce membre comme leur implémentation. Dans l’exemple suivant, tous les appels à Paint appellent la même méthode. Ce premier exemple définit les types :

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");
    }
}

L’exemple suivant appelle les méthodes :

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

Vous ne souhaiterez cependant peut-être pas que la même implémentation soit appelée pour les deux interfaces. Pour appeler une implémentation différente en fonction de l’interface utilisée, vous pouvez implémenter explicitement un membre d’interface. Une implémentation d’interface explicite est un membre de classe qui est uniquement appelé via l’interface spécifiée. Nommez le membre de classe en le préfixant avec le nom de l’interface et un point. Par exemple :

public class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}

Le membre de classe IControl.Paint est disponible uniquement via l’interface IControl et ISurface.Paint est disponible uniquement via ISurface. Les deux implémentations de méthode sont distinctes et aucune d’elles n’est disponible directement sur la classe. Par exemple :

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

L’implémentation explicite est également utilisée pour résoudre les cas où deux interfaces déclarent chacune des membres différents du même nom, comme une propriété et une méthode. Pour implémenter les deux interfaces, une classe doit utiliser une implémentation explicite pour la propriété P, ou la méthode P, ou les deux, pour éviter une erreur du compilateur. Par exemple :

interface ILeft
{
    int P { get;}
}
interface IRight
{
    int P();
}

class Middle : ILeft, IRight
{
    public int P() { return 0; }
    int ILeft.P { get { return 0; } }
}

Une implémentation d’interface explicite n’a pas de modificateur d’accès, car elle n’est pas accessible en tant que membre du type dans lequel elle est définie. Elle n’est accessible qu’en cas d’appel via une instance de l’interface. Si vous spécifiez un modificateur d’accès pour une implémentation d’interface explicite, vous obtenez l’erreur du compilateur CS0106. Pour plus d’informations, consultez interface (Référence C#).

Vous pouvez définir une implémentation pour les membres déclarés dans une interface. Si une classe hérite d’une implémentation de méthode à partir d’une interface, cette méthode n’est accessible qu’à l’aide d’une référence du type d’interface. Le membre hérité n’apparaît pas dans le cadre de l’interface publique. L’exemple suivant définit une implémentation par défaut pour une méthode d’interface :

public interface IControl
{
    void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
    // Paint() is inherited from IControl.
}

L’exemple suivant appelle l’implémentation par défaut :

var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();

Toute classe qui implémente l’interface IControl peut remplacer la méthode par défaut Paint , en tant que méthode publique ou en tant qu’implémentation d’interface explicite.

Voir aussi