2010-03-26 10 views
26

Hier ist die Geschichte. Ich habe eine Schnittstelle erstellt, IVehicle. Ich habe die Schnittstelle in meiner Klasse Vehicle.cs explizit implementiert.Warum kann ich keine Methoden innerhalb einer Klasse aufrufen, die explizit eine Schnittstelle implementiert?

Hier ist meine Schnittstelle:

Interface IVehicle 
{ 
     int getWheel(); 
} 

hier ist meine Klasse:

class Vehicle: IVehicle 
{ 

    public int IVehicle.getWheel() 
    { 
     return wheel; 
    } 

    public void printWheel() 
    { 
     Console.WriteLine(getWheel()); 
    } 
} 

Beachten Sie, dass getWheel() explizit umgesetzt. Wenn ich nun versuche, diese Methode innerhalb meiner Fahrzeugklasse aufzurufen, erhalte ich einen Fehler, der anzeigt, dass getWheel() im aktuellen Kontext nicht existiert. Kann mir jemand helfen zu verstehen, was ich falsch mache?

+0

als Java Person mit rufen schaffen könnte, frage ich mich, warum diese gefaltete Sache existiert? Warum sollte jemand das Obenstehende existieren lassen? Welchen Vorteil hat es? –

+0

Das Angeben eines Sichtbarkeitsmodifizierers für ein explizit implementiertes Element ist ein Syntaxfehler. Auf das Mitglied kann immer zugegriffen werden, sobald das Objekt für Ihren Schnittstellentyp bestimmt wurde. – Trillian

+3

@mP Wenn Sie mehrere Schnittstellen mit einem gemeinsamen Member implementieren, können Sie verschiedene Definitionen für jede Schnittstelle angeben. Es wird auch hinzugefügt, um Intellisense zu bereinigen, da die expliziten Elemente nicht sichtbar oder verwendbar sind, es sei denn, Sie werden in die richtige Schnittstelle umgewandelt. –

Antwort

35

Wenn Sie die Schnittstelle explizit implementieren, müssen Sie zuerst das Objekt auf die Schnittstelle umwandeln, dann können Sie die Methode aufrufen. Mit anderen Worten, die Methode ist nur verfügbar, wenn die Methode für das Objekt als Schnittstellentyp und nicht als konkreter Typ aufgerufen wird.

class Vehicle: IVehicle { 

    public int IVehicle.getWheel() 
    { 
     return wheel; 
    } 

    public void printWheel() 
    { 
     Console.WriteLine(((IVehicle)this).getWheel()); 
    } 
} 

Weitere Informationen finden Sie unter reference bei MSDN. Hier ist der relevante Ausschnitt:

Es ist nicht möglich, über einen vollständig qualifizierten Namen in einem Methodenaufruf, einem Eigenschaftenzugriff oder einem Indexerzugriff auf eine explizite Schnittstellenmemberimplementierung zuzugreifen. Auf eine explizite Schnittstellenmemberimplementierung kann nur über eine Schnittstelleninstanz zugegriffen werden, und wird in diesem Fall einfach durch ihren Mitgliedsnamen referenziert.

Für was es wert ist - dies ist wahrscheinlich keine besonders gute Verwendung der expliziten Schnittstellenimplementierung. Normalerweise möchten Sie die explizite Implementierung verwenden, wenn Sie eine Klasse mit einer vollständigen Schnittstelle für typische Operationen haben, aber auch eine Schnittstelle implementieren, die einige dieser Operationen ersetzen kann. Das kanonische Beispiel ist eine File Klasse, die IDisposable implementiert. Es würde eine Close() Methode haben aber erforderlich sein, Dispose() zu implementieren. Bei der Behandlung als File würden Sie Open/Close verwenden. Wenn es jedoch in einer using-Anweisung geöffnet wird, behandelt es es als IDisposable und ruft Dispose auf. In diesem Fall ruft Dispose einfach Close. Sie möchten nicht notwendigerweise Dispose als Teil der File Implementierung verfügbar machen, da das gleiche Verhalten von Close verfügbar ist.

+0

Danke. Ich habe es nur getan, um mir zu beweisen, dass ich es schaffen kann. Bis zu diesem Punkt gab das Buch, das ich verwende, keinen Grund, der auf die Notwendigkeit hinweist, die Schnittstelle explizit zu implementieren. – tyrone302

+0

Ein weiteres gängiges Beispiel hierfür sind die generierten '.Designer' -Dateien einer Winforms-App. Jedes Steuerelement wird zwischen einem Paar der Methoden ".BeginInit()" und ".EndInit()" initialisiert, aber diese Aufrufe werden alle * nach dem * Umwandeln des Steuerelements in "ISupportInitialize" vorgenommen. – kdbanman

11

Nach MSDN:

Es ist möglich, eine Schnittstelle Mitglied explizit die Schaffung eines Klasse Mitglied zu implementieren, die nur über die Schnittstelle genannt wird, und ist spezifisch an dieser Schnittstelle.

Und im C# language specifications:

Es ist nicht möglich, eine explizite Schnittstellenmember Implementierung durch seine voll qualifizierten Namen in einem Methodenaufruf zuzugreifen, Eigenschaft Zugriff oder Indexer-Zugriff. Ein explizites Interface-Mitglied Implementierung kann nur über eine Schnittstelleninstanz auf zugegriffen werden und wird in diesem Fall einfach durch seinen Mitgliedsname referenziert.

Um auf dieses Mitglied zuzugreifen, können Sie zuerst die Klasse auf die Schnittstelle umwandeln und dann darauf zugreifen.

3

Um eine Menge langweilige zu vermeiden auf Ihre Klasse wirft, Sie einen Zeiger als Schnittstelle Typ

public class Foo : IBar 
{ 
    readonly IBar bar; 
    public Foo() 
    { 
     bar = this; 
    } 
} 

Und dann Mitglieder bar.

Verwandte Themen