2009-04-27 9 views
43

In un'intervista qualche tempo fa per una posizione su .NET l'intervistatore mi ha chiesto "per cosa utilizzeresti un'interfaccia privata?".Cos'è un'interfaccia privata?

Gli ho chiesto se intendesse la differenza tra implementazione di interfaccia implicita o esplicita a cui ha risposto no.

Quindi mi chiedo:

  1. cosa voleva dire?
  2. Per cosa utilizzeresti un'interfaccia privata?

risposta

30

Un'interfaccia potrebbe essere privato all'interno di un'altra classe

public class MyClass 
{ 
    private interface IFoo 
    { 
     int MyProp { get; } 
    } 

    private class Foo : IFoo 
    { 
     public int MyProp { get; set; } 
    } 

    public static void Main(string[] args) 
    { 
     IFoo foo = new Foo(); 
     return foo.MyProp; 
    } 
} 

in termini di utilità semplicemente nasconde altro codice, anche all'interno dello stesso complesso, che detta interfaccia esistente. L'utilità di questo non è terribilmente alta secondo me.

Explicit interface implementation è una questione diversa, ha alcuni casi molto utili (soprattutto quando si lavora con i generici e interfacce più anziani non generici), ma non vorrei definirla 'interfacce private' e non direi che il termine è comunemente utilizzato in tal modo .

Utilizzando le due tecniche insieme si può fare: si

public class MyClass 
{ 
    private interface IFoo 
    { 
     int MyProp { get; } 
    } 

    public class Foo : IFoo 
    { 
     int IFoo.MyProp { get; set; } 
    } 

    public static void Main(string[] args) 
    { 
     IFoo foo = new Foo(); 
     return foo.MyProp; 
    } 
} 

public class HiddenFromMe 
{ 
    public static void Main(string[] args) 
    { 
     MyClass.Foo foo = new MyClass.Foo(); 
     return foo.MyProp; // fails to compile 
    } 
} 

Questo permette di esporre le classi nidificate in qualche modo pur consentendo la classe padre per richiamare i metodi su di loro che il mondo esterno non può. Questo è un caso potenzialmente utile ma non è qualcosa che vorrei usare molto spesso. Sicuramente il suo uso in un'intervista sa di essere un caso limite che l'intervistatore usa perché l'hanno visto e anche se era 'interessante'

+5

Anche se questo è vero, non sarebbe uno degli usi più inutili delle interfacce? Non riesco a capire perché mai useresti una tale costruzione. – Razzie

+0

faticando a pensare a molto di un caso d'uso per questo, o almeno a un caso d'uso che non comporta anche la creazione di una classe di Dio – annakata

+0

Questo è ciò che ho interpretato la domanda nel senso che, in tal caso, era solo una domanda sciocca il intervistatore chiesto! – RichardOD

11

Da this link.

interfaccia privata Inheritance

Storicamente, le lingue hanno permesso l'ereditarietà privata. In C++, puoi ereditare da un tipo senza essere polimorficamente compatibile con quel tipo. È solo un modo conveniente per riutilizzare un'implementazione. Nel CTS, non è possibile eseguire l'ereditarietà di implementazione privata. Ma puoi usare l'ereditarietà dell'interfaccia privata.

L'ereditarietà dell'interfaccia privata è in realtà solo un modo per nascondere i metodi dall'API pubblica di un tipo. Sono compilati in metodi privati ​​ma sono effettivamente accessibili attraverso la mappa dell'interfaccia di un tipo. In altre parole, possono essere richiamati solo attraverso un riferimento digitato come interfaccia su cui è definito il metodo. Un esempio renderà questo più facile da capire:

class PrivateImplementer : IFoo 
{ 
    void IFoo.Foo() 
    { 
     Console.WriteLine("PrivateImplementer::IFoo.Foo"); 
    } 
} 

In questo caso, PrivateImplementer è pubblicamente noto per implementare IFoo. Pertanto, un'istanza può essere trattata polimorficamente come un'istanza di IFoo. Ma in realtà non puoi chiamare Foo su di esso a meno che non lo tratti come IFoo. Questo codice illustra questo:

PrivateImplementer p = new PrivateImplementer(); 
p.Foo(); // This line will fail to compile 
IFoo f = p; 
f.Foo(); 

È possibile selezionare i metodi individuali di un'interfaccia per implementare privatamente. Ad esempio, se PrivateImplementer implementato IFooBar, potrebbe scegliere di implementare Foo in privato, ma Bar pubblicamente utilizzando la sintassi ordinaria.

In pratica, non ci sono molti casi comuni in cui si utilizza l'implementazione privata. La libreria System.Collections.Generic utilizza questo approccio per implementare segretamente tutte le interfacce legacy System.Collections legacy. Ciò rende la compatibilità all'indietro "funziona", ad esempio passando un'istanza di List<T> a un metodo che prevede che un IList funzionerà correttamente. In questo esempio specifico, ingombrare le nuove API di tipo sarebbe stato un peccato (ci sono parecchi metodi necessari per l'interoperabilità debolmente tipizzata).

"No", è una risposta piuttosto scadente se cercava di scoprire quello che sapevi. Sembra uno che vuole solo mostrare quanto ne sa.

+2

Hi Mark, ho visto che anche la pagina Web non è proprio uguale all'implementazione di un'interfaccia esplicita? – RichardOD

+1

Ho intenzione di fare +1 su questo perché è noto come ereditarietà dell'interfaccia privata. – annakata

+6

Questa è l'implementazione esplicita dell'interfaccia e l'intervistatore ha dichiarato che NON era quello che intendeva. – GrahamS

1

Proprio come una classe interna (che è anche privata) è possibile utilizzare un'interfaccia privata in una classe esistente.

1

Ho cercato su google un po 'e ho trovato l'articolo this che spiega come utilizzare le interfacce private per fornire interfacce diverse a client diversi. Questa è la storia del C++.

Non penso che questo possa essere applicato a C# tho, perché lo stesso effetto IMO può essere ottenuto con interfacce esplicite e client che eseguono il cast dell'host su un'interfaccia appropriata.

Forse qualcun altro in grado di vedere qualcosa che ho perso lì ....

Ho trovato anche questo a MSDN:

I metodi di interfaccia hanno pubblica l'accessibilità, che non può essere cambiata dal tipo di implementazione . Un'interfaccia interna crea un contratto che è non previsto per essere implementato all'esterno dello l'assembly che definisce l'interfaccia . Un tipo pubblico che implementa un metodo di un'interfaccia interna utilizzando il modificatore virtuale consente di sovrascrivere il metodo da un tipo derivato che si trova all'esterno dell'assembly . Se un secondo tipo nell'assembly chiama il metodo e prevede un contratto solo interno, il comportamento potrebbe essere compromesso quando, , invece, viene eseguito il metodo sottoposto a override nell'assembly esterno. Questo crea una vulnerabilità di sicurezza.

2

ShuggyCoUk dà buona risposta ma con tale commento

Questo è un caso potenzialmente utile, ma non è qualcosa che vorrei usare molto spesso. Certo il suo uso in un'intervista sa di essere un caso di confine l'intervistatore sta usando perché hanno visto e anche se era 'interessante'

io, devo dire, non è sicuramente la capacità di intervistatori solo intelligenti.

Qui è Realization of Full State Machine (FSM) with inheritance and unitest support, che è un buon esempio di utilizzo di interfacce private/protette.

Era una risposta alle domande What is the C# equivalent of friend? e Why does C# not provide the C++ style 'friend' keyword? e, di fatto, anche alla tua domanda.

Problemi correlati