Qual è la differenza tra l'implementazione di un'interfaccia in modo esplicito o implicito?


64

In Visual Studio posso fare clic con il pulsante destro del mouse su un'interfaccia e scegliere Implementa interfaccia o Implementa esplicitamente l'interfaccia.

Schermata di Visual Studio

public class Test : ITest
{
    public string Id // Generated by Implement Interface
    {
        get { throw new NotImplementedException(); }
    }

    string ITest.Id // Generated by Implement Interface Explicitly
    {
        get { throw new NotImplementedException(); }
    }
}

L'unica differenza che vedo tra i due è che il nome dell'interfaccia viene aggiunto alle proprietà e ai metodi dell'interfaccia quando vengono creati se si sceglie di implementare l'interfaccia in modo esplicito.

Trovo che renda il codice un po 'più leggibile poiché posso vedere da dove proviene quel metodo / proprietà, tuttavia questo fa qualche differenza nel modo in cui la classe viene utilizzata o compilata? E importa davvero se implemento le mie interfacce in modo implicito o esplicito?

Risposte:


51

Controlla la risposta migliore di Andrew Barrett per "implementazione implicita vs esplicita dell'interfaccia" su SO .

Fondamentalmente:

  • Implicito: accedi ai metodi e alle proprietà dell'interfaccia come se facessero parte della classe.
  • Esplicito: è possibile accedere a metodi e proprietà solo trattando la classe come interfaccia implementata.

Esempi di codice:

Implicito:

Test t = new Test();
t.Id; // OK
((ITest)t).Id; // OK

Esplicito:

Test t = new Test();
t.Id; // Not OK
((ITest)t).Id; // OK

In termini di "quando" devi implementare esplicitamente un'interfaccia, è quando la tua classe ha già un metodo con la stessa firma di uno dei metodi della tua interfaccia, oppure quando la tua classe implementa diverse interfacce che condividono metodi con le stesse firme ma contratti incompatibili.


1
Ho anche trovato utile l'implementazione esplicita per avere una sorta di interfaccia "nascosta" con operazioni non sicure. Fa inoltre risaltare maggiormente le chiamate a questi metodi, il che è positivo per le cose non sicure.
Tamás Szelei,

Vale anche la pena ricordare che l'utilizzo delle interfacce esplicite comporta un costo in termini di prestazioni, dal momento che deve box / unbox l'oggetto ogni volta che si fa riferimento alla proprietà / metodo. Per questo motivo, è meglio usare interfacce implicite, se possibile
Rachel,

3
@ Rachel: per quanto ne so, il costo delle prestazioni si applica solo ai tipi di valore.
Groky

8

C'è anche una differenza nel modo in cui chiami il metodo.

Quando si utilizza un'implementazione esplicita dell'interfaccia, è necessario utilizzare il tipo di interfaccia per chiamare l'implementazione specifica.

Pertanto, per chiamare il codice è necessario utilizzare una variabile di tipo ITestper accedere ITest.Id.

L'articolo Implementazione esplicita dell'interfaccia (Guida per programmatori C #) su MSDN ha un buon esempio.



4

EDIT: Non dovrebbe fare la differenza Non dovresti farlo a meno che la tua classe non implementi due interfacce con le stesse proprietà, poiché dovrai eseguire il cast all'interfaccia pertinente prima di poter accedere al membro:

public interface ITest
{
    string Id { get; }
}

public interface IAlsoTest
{
    string Id { get; }
}

public interface ITestToo
{
    int Id { get; }
}

public class Test : ITest, IAlsoTest
{
    // Valid implicit implementation of BOTH interfaces
    public string Id
    {
        get { throw new NotImplementedException(); }
    }
}

public class TestSeparately : ITest, ITestToo
{
    // This way we can do different things depending
    // on which interface the callee called from.
    string ITest.Id
    {
        get { throw new NotImplementedException(); }
    }

    int ITestToo.Id
    {
        get { throw new NotImplementedException(); }
    }
}

public class TestOuch
{
    public void DoStuff()
    {
        var ts = new TestSeparately();

        // Works
        Console.WriteLine(((ITest)ts).Id);

        // Works
        Console.WriteLine(((ITestToo)ts).Id);

        // Not valid! Which one did we want to call?
        Console.WriteLine(ts.Id);
    }
}

L'utilizzo dell'esempio vale quando si implementa esplicitamente un membro dell'interfaccia anche se si utilizza solo un'unica interfaccia (che dimentico sempre: S), quindi proverei a evitare l'implementazione esplicita ogni volta che è possibile, poiché nasconderebbe i membri della classe se " non trasmettere alla giusta interfaccia (il che è abbastanza confuso).


3

Sulla base della risposta di Jalayan,

  • Implicito: accedi ai metodi e alle proprietà dell'interfaccia come se facessero parte della classe.
  • Esplicito: è possibile accedere a metodi e proprietà solo trattando la classe come interfaccia implementata.

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.