Implementare membri di interfaccia espliciti in una classe

Completato

In C#, l'implementazione esplicita dell'interfaccia consente a una classe di implementare i membri dell'interfaccia in modo che siano accessibili solo tramite l'interfaccia, non l'istanza della classe. Ciò è utile quando una classe implementa più interfacce con membri con la stessa firma.

Più interfacce in una classe

Una classe in C# può implementare più interfacce, consentendogli di ereditare il comportamento da varie origini. La possibilità di combinare più interfacce è fondamentale perché C# non supporta più ereditarietà delle classi. L'implementazione di più interfacce consente a una classe di avere funzionalità diverse e garantisce che segua le regole impostate da tali interfacce.

  • Le interfacce definiscono un gruppo di funzionalità correlate.
  • Una classe o uno struct deve implementare tutti i membri delle interfacce che eredita.
  • Le interfacce possono contenere metodi, proprietà, eventi e indicizzatori.

Di seguito sono riportate due interfacce semplici per l'esempio:

public interface IEnglishDimensions
{
    float Length();
    float Width();
}

public interface IMetricDimensions
{
    float Length();
    float Width();
}

Membri espliciti dell'interfaccia

In C# una classe può ereditare da una sola classe, ma può implementare più interfacce. Ciò è particolarmente importante quando diverse interfacce hanno gli stessi nomi di membro. Per evitare confusione, viene usata l'implementazione esplicita dell'interfaccia.

L'implementazione esplicita dell'interfaccia garantisce che ogni membro di un'interfaccia abbia un'implementazione univoca, impedendo i conflitti. Viene inoltre chiarita l'interfaccia a cui appartiene un membro quando una classe implementa due o più interfacce con gli stessi nomi di membro. L'implementazione esplicita dell'interfaccia consente a una classe di soddisfare i requisiti di più interfacce, fornendo funzionalità diverse.

Per implementare in modo esplicito un membro di un'interfaccia, aggiungere il nome dell'interfaccia e un punto prima del nome del membro. Ecco un esempio:

public class Box : IEnglishDimensions, IMetricDimensions
{
    float IEnglishDimensions.Length()
    {
        return 30.0f;
    }

    float IEnglishDimensions.Width()
    {
        return 20.0f;
    }

    float IMetricDimensions.Length()
    {
        return 76.2f;
    }

    float IMetricDimensions.Width()
    {
        return 50.8f;
    }
}

In questo codice la Box classe implementa due interfacce: IEnglishDimensions e IMetricDimensions. Entrambe le interfacce hanno membri denominati Length e Width. Per evitare confusione, ogni membro viene collegato in modo esplicito alla relativa interfaccia.

Annotazioni

I membri dell'interfaccia implementati in modo esplicito non dispongono di modificatori di accesso come public, privatee così via. È possibile accedervi solo tramite un'istanza dell'interfaccia, non la classe . Ciò significa che non è possibile chiamare Box.Length(), ma è possibile chiamare IEnglishDimensions.Length() se si dispone di un'istanza di Box che viene considerata come .IEnglishDimensions

Usare membri di interfaccia espliciti

È necessario creare istanze delle interfacce e chiamare i relativi membri per eseguire e testare il codice che utilizza membri di interfaccia espliciti. In questo modo si garantisce che venga richiamata l'implementazione corretta in base al tipo di interfaccia.

Box box = new Box();
IEnglishDimensions eDimensions = box;
IMetricDimensions mDimensions = box;

Console.WriteLine($"Length in inches: {eDimensions.Length()}");
Console.WriteLine($"Width in inches: {eDimensions.Width()}");
Console.WriteLine($"Length in centimeters: {mDimensions.Length()}");
Console.WriteLine($"Width in centimeters: {mDimensions.Width()}");

In questo esempio, viene effettuato il cast dell'istanza della classe Box sia a IEnglishDimensions che a IMetricDimensions per accedere ai membri espliciti dell'interfaccia. L'output visualizza le dimensioni sia in inglese che in unità di metrica.

Length in inches: 30
Width in inches: 20
Length in centimeters: 76.2
Width in centimeters: 50.8

In C# è possibile implementare più interfacce in una classe, usando l'implementazione esplicita dell'interfaccia per risolvere i conflitti di denominazione quando i membri hanno le stesse firme. I membri implementati in modo esplicito sono accessibili tramite l'istanza dell'interfaccia, non l'istanza della classe, garantendo funzionalità appropriate ed evitando ambiguità. Questo approccio migliora la gestibilità del codice definendo chiaramente il comportamento previsto per ogni interfaccia, semplificando la comprensione e l'estensione della codebase.