Qual è la differenza tra l'implementazione di un'interfaccia esplicitamente o implicitamente?

42

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

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à dell'interfaccia e ai metodi quando vengono creati se si sceglie di implementare l'interfaccia in modo esplicito.

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

    
posta Rachel 22.02.2012 - 15:29
fonte

4 risposte

35

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

In sostanza:

  • Implicito: accedi ai metodi e alle proprietà dell'interfaccia come se fossero parte della classe.
  • Esplicito: puoi accedere ai metodi e alle proprietà solo quando si tratta 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 un'interfaccia esplicitamente, è quando la tua classe ha già un metodo con la stessa firma di uno dei metodi della tua interfaccia, o quando la tua classe implementa diverse interfacce che condividono metodi con le stesse firme.

    
risposta data 22.02.2012 - 15:36
fonte
8

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

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

Quindi, nel codice chiamante dovresti usare una variabile di tipo ITest per accedere a ITest.Id .

L'articolo Implementazione esplicita dell'interfaccia (C # Programming Guide) su MSDN ha un buon esempio.

    
risposta data 22.02.2012 - 15:34
fonte
3

Permette di implementare due interfacce che definiscono lo stesso metodo. Tuttavia, se si implementa esplicitamente l'interfaccia, è possibile accedere ai metodi solo quando la variabile viene digitata su tale interfaccia esplicita.

Vedi: Tutorial Implementazione esplicita dell'interfaccia

    
risposta data 22.02.2012 - 15:35
fonte
3

EDIT: Non dovrebbe fare la differenza Non dovresti farlo a meno che la tua classe non implementa due interfacce con le stesse proprietà, dato che dovrai eseguire il cast sull'interfaccia relativa prima puoi 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 implementi esplicitamente un membro dell'interfaccia anche se utilizzi una sola interfaccia (che dimentico sempre: S), quindi cercherò di evitare l'implementazione esplicita quando possibile, in quanto nasconderà i membri della classe se non sono trasmessi all'interfaccia giusta (che è abbastanza confusa).

    
risposta data 22.02.2012 - 15:38
fonte

Leggi altre domande sui tag