2009-04-27 16 views
43

In einem Interview vor einiger Zeit für eine .NET-Position fragte mich der Interviewer, "wofür würden Sie eine private Schnittstelle verwenden?".Was ist eine private Schnittstelle?

Ich fragte ihn, ob er den Unterschied zwischen impliziter und expliziter Schnittstellenimplementierung meinte, auf den er nein antwortete.

Also ich frage mich:

  1. Was er damit meinte?
  2. Wozu würden Sie eine private Schnittstelle verwenden?

Antwort

30

könnte eine Schnittstelle innerhalb einer anderen Klasse

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 Bezug auf Nützlichkeit versteckt es einfach von anderem Code, auch innerhalb derselben Baugruppe, die die Schnittstelle vorhanden ist privat. Der Nutzen davon ist meiner Meinung nach nicht sehr hoch.

Explicit interface implementation ist eine andere Sache, hat einige sehr nützliche Fälle (vor allem bei der Arbeit mit Generika und älteren nicht generischen Schnittstellen), aber ich würde es nicht "private Schnittstellen" nennen und würde nicht sagen, dass der Begriff auf diese Weise verwendet wird .

Mit Hilfe der beiden Techniken zusammen können Sie tun:

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 
    } 
} 

Auf diese Weise können Sie die verschachtelten Klassen in irgendeiner Art und Weise zu belichten, während die Elternklasse ermöglicht ihnen aufzurufen Methoden, dass die Außenwelt nicht. Dies ist ein potentiell nützlicher Fall, aber ich möchte ihn nicht oft verwenden. Sicherlich ist es in einem Interview Smacks von einem Grenzfall der Interviewer verwendet wird, weil sie es gesehen haben und obwohl es "interessant" war

+5

Obwohl das stimmt, wäre das nicht einer der nutzlosesten Nutzungen von Schnittstellen? Ich kann nicht verstehen, warum Sie jemals solch eine Konstruktion benutzen würden. – Razzie

+0

kämpfen, um viel von einem Anwendungsfall dafür zu denken, oder zumindest einen Anwendungsfall, der nicht auch eine Gottklasse zu schaffen – annakata

+0

Das ist, was ich die Frage als Bedeutung interpretiert, in diesem Fall war es nur eine dumme Frage der Interviewer gefragt! – RichardOD

11

Von this link.

private Schnittstelle Inheritance

Historisch gesehen, haben Sprachen private Vererbung gestattet. In C++ können Sie von einem Typ erben, ohne mit diesem Typ polymorph kompatibel zu sein. Es ist nur eine bequeme Möglichkeit, eine Implementierung wiederzuverwenden. Im CTS können Sie keine private Implementierungsvererbung ausführen. Sie können jedoch die private Schnittstellenvererbung verwenden.

Private Schnittstelle Vererbung ist wirklich nur eine Möglichkeit, Methoden aus der öffentlichen API eines Typs zu verbergen. Sie werden in private Methoden kompiliert, sind aber tatsächlich über die Schnittstellenkarte eines Typs zugänglich. Mit anderen Worten, sie können nur über eine Referenz aufgerufen werden, die als Schnittstelle eingegeben wurde, auf der die Methode definiert ist. Ein Beispiel soll dies leichter verständlich machen:

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

In diesem Fall wird PrivateImplementer öffentlich zu implementieren IFoo bekannt. Somit kann eine Instanz polymorph als eine Instanz von IFoo behandelt werden. Aber du kannst Foo nicht wirklich anrufen, wenn du es nicht als IFoo behandelst. Dieser Code demonstriert das:

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

Sie können einzelne Methoden einer Schnittstelle auswählen, um privat zu implementieren. Zum Beispiel, wenn PrivateImplementer implementiert IFooBar, könnte es sich entscheiden, Foo privat zu implementieren, aber Bar öffentlich mit der üblichen Syntax.

In der Praxis gibt es nicht viele Fälle, in denen Sie eine private Implementierung verwenden würden. Die System.Collections.Generic-Bibliothek verwendet diesen Ansatz zur geheimen Implementierung aller älteren, schwach typisierten Schnittstellen von System.Collections. Dies macht Rückwärtskompatibilität "einfach funktionieren", zum Beispiel die Übergabe einer Instanz von List<T> an eine Methode, die eine IList erwartet, wird gut funktionieren. In diesem speziellen Beispiel wäre es sehr schade gewesen, die neuen Typ-APIs zu überlisten (für die schwach typisierte Interoperabilität gibt es einige Methoden).

"Nein," ist eine ziemlich schlechte Antwort, wenn er herausfinden wollte, was Sie wussten. Klingt wie jemand, der nur zeigen will, wie viel sie wissen.

+2

Hallo Markus, ich sah diese Webseite zu - ist das nicht genau das gleiche wie eine explizite Schnittstellenimplementierung? – RichardOD

+1

Ich werde dies +1 geben, weil es als Private Interface Vererbung bekannt ist. – annakata

+6

Das ist explizite Interface-Implementierung und der Interviewer sagte, das sei NICHT das, was er meinte. – GrahamS

1

Genau wie eine innere Klasse (die auch privat ist) können Sie eine private Schnittstelle verwenden in einer vorhandenen Klasse.

1

Ich googelte um ein bisschen herum und fand this Artikel, der erklärt, wie private Schnittstellen benutzt werden können, um verschiedenen Klienten unterschiedliche Schnittstellen zur Verfügung zu stellen. Das ist C++ - Geschichte.

Ich denke nicht, dass dies auf C# tho angewendet werden kann, da derselbe IMO-Effekt mit expliziten Schnittstellen und Clients erzielt werden kann, die Host auf entsprechende Schnittstelle werfen.

Vielleicht jemand anderes etwas sehen kann ich es verpasst ....

Ich fand auch diese bei MSDN:

Schnittstelle Methoden Öffentlichkeit Zugänglichkeit, die nicht durch die Umsetzung Typ geändert werden kann . Eine interne Schnittstelle erstellt einen Vertrag, der nicht für die Implementierung außerhalb der die Assembly, die die Schnittstelle definiert ist. Ein öffentlicher Typ implementiert eine Methode einer internen Schnittstelle mit dem virtuellen Modifikator ermöglicht die Methode von einen abgeleiteten Typ überschrieben werden, der außerhalb der Assembly ist. Wenn ein zweiter Typ in der definierenden Baugruppe die Methode aufruft und einen Nur-internen Vertrag erwartet, kann das Verhalten beeinträchtigt sein, wenn stattdessen die überschriebene Methode in der Außenbaugruppe ausgeführt wird. Diese schafft eine Sicherheitslücke.

2

ShuggyCoUk gibt gute Antwort, aber mit einem solchen Kommentar

Dies ist eine potenziell nützliche Fall aber ist nicht etwas, was ich wünschte, würde sehr häufig verwenden. Sicherlich ist es die Verwendung in einem Interview schmatzt einen Grenzfall ist der Interviewer mit, weil sie es gesehen haben und obwohl es ‚interessant‘ war

ich muß sagen, es ist definitiv nicht die Fähigkeit für nur klug Interviewern.

Hier ist Realization of Full State Machine (FSM) with inheritance and unitest support, die ein gutes Beispiel für private/geschützte Schnittstellen Verwendung ist.

Es war eine Antwort auf Fragen What is the C# equivalent of friend? und Why does C# not provide the C++ style 'friend' keyword? und in der Tat auch auf Ihre Frage.

Verwandte Themen