2017-09-05 2 views
0

Normalerweise implementieren wir Schnittstellen explizit, wenn es nicht richtig ist, direkt von der Klasse implementer auf interface member zuzugreifen. Wetter muss es intern sein oder es verursacht Konflikte mit API-Design oder wenn es die Wahrscheinlichkeit von missbräuchlichen Methoden erhöht.Warum ist es möglich, die explizite Implementierung zu überschreiben?

Implementierung Mitglieder individuell für mehrere Schnittstellen mit anderen Logik ist absolut in meinem Kopf entmutigt so das wird hier nicht case

Compiler erlaubt es nicht, eine solche Implementierung als virtuellen machen, weil es keinen Sinn macht, und ich denke, es ist Recht. Normalerweise ist eine explizite Implementierung sehr sensitiv und deshalb versuchen Sie diese zu verstecken.

Allerdings fand ich folgende Art und Weise des über Reiten explizite Implementierung (es ist nicht genau das, außer Kraft setzen, aber sein Betrug Alternative)

fand ich diese überraschenden und sehr enttäuschend. Meine Frage ist, warum folgender Code erlaubt ist und perfekt funktioniert? Ich habe erwartet, Fehler zu bekommen, dass die Schnittstelle bereits explizit implementiert ist.

Dies ist nur einfaches Beispiel ist Problem zu reproduzieren

static void Main(string[] args) 
{ 
    var b = new Base(); 
    ((IInterface)b).Write(); 

    var c = new Child(); 
    ((IInterface)c).Write(); 
} 
public interface IInterface 
{ 
    void Write(); 
} 
public class Base : IInterface 
{ 
    void IInterface.Write() 
    { 
     Console.WriteLine("Base"); 
    } 
} 
public class Child : Base, IInterface // hack is here. Re Implemented :/ 
{ 
    void IInterface.Write() 
    { 
     Console.WriteLine("Child"); 
    } 
} 

Outputs 

    Base 
    Child 
+0

Wie haben Sie es geschafft, die Codeformatierung so zu vermasseln? – CodeCaster

+0

Betrachten Sie einen etwas komplizierteren Fall, die Methode 'Write' sollte alle internen Variablen der Klasse drucken. Wenn "Kind" nun mehr Variablen hat, sollte es die Schnittstelle wieder implementieren, da es mehr Variablen als die "Basis" enthalten könnte. Ich sehe nicht, dass Sie die Neuimplementierung von Schnittstellen verhindern wollen. –

+0

@CodeCaster Ich tippte es von meinem Handy. Ich habe Text mit Code von meinem PC an mein Telefon gesendet und dann kopiert. SO war nicht glücklich mit meiner Kopie Paste. –

Antwort

2

Warum folgender Code erlaubt ist und perfekt funktioniert?

Da die Spezifikationen so sagen:

Es ist ein Fehler bei der Kompilierung für eine explizite Schnittstellenmemberimplementierung Zugriffsmodifikatoren aufzunehmen, und es ist ein Fehler bei der Kompilierung der Modifikatoren umfassen abstrakte , virtuell, überschreiben oder statisch.

Doch in Polymorphismus, sagt man "Je mehr abgeleiteten Typ besser weiß", von den Spezifikationen wieder:

abgeleiteten Klassen erweitern und spezialisieren Klassen Basis

So Der am weitesten abgeleitete Typ, der diese Schnittstelle explizit implementiert, wird beim Aufrufen dieses Schnittstellenelements aufgerufen.

+0

Das macht Sinn, ich habe nicht in Ihrer Perspektive gesehen. Gibt es einen Weg dies zu verhindern? Angenommen, Sie entwickeln eine API und können die Schnittstelle nicht intern machen. –

+4

Mark 'class Base' wie versiegelt. Wenn Sie nur Schnittstellen für eine API offen legen, keine Klassen, können Sie nicht steuern, wie Entwickler sie verwenden. – CodeCaster

+0

Ich sehe, aber ich wollte, dass es vererbbar ist, so dass es erweitert werden kann. Ich denke, was ich will kann nicht erreicht werden. Ich könnte stattdessen Wrapperklasse verwenden oder interne Felder verwenden. Danke für die Antwort. –

0

Ich schlage vor, Sie auf dem niedrigen Niveau Übersetzung zu denken, von C# in nativen Code: die Schnittstelle Vererbung Neudeklaration, und die eine oder mehrere seiner Methoden überschreiben, Erzwingt das Umschreiben der VMT - Virtuelle Methodentabelle (Schnittstellenmethoden sind virtuell von Entwurf).

Verwandte Themen