Frage

Ausgang:
B-> Hallo! von Explicit.

Sollte es nicht sein:
A-> Hallo! von Explicit.

Warum nicht explizite Umwandlung (IHello) ein Anruf IHello.Hello () der Klasse A?

interface IHello
{
    void Hello();
}

class A : IHello
{

    public virtual void Hello()
    {
        Console.WriteLine("A->Hello!");
    }

    void IHello.Hello()
    {
        Console.WriteLine("A->Hello! from Explicit.");
    }
}

class B : A, IHello
{
    public override void Hello()
    {
        Console.WriteLine("B->Hello!");
    }

    void IHello.Hello()
    {
        Console.WriteLine("B->Hello! from Explicit.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new B();
        ((IHello)a).Hello();
    }
}
War es hilfreich?

Lösung

Nein, sollte es nicht.

Der Aufruf von Hello entspricht der kommentierten-out ein - die Strecke zu bekommen eine IHello keine Rolle spielt (es sei denn, es Ausführungszeit Überprüfung oder Umwandlung erfordert); die Kompilierung-Typ ist IHello nur so oder so, und das Interface-Mapping ist die gleiche Sie aber dorthin gelangen.

Wenn eine Schnittstelle explizit mehr als einmal in der Typenhierarchie implementiert ist, die Umsetzung in den meisten abgeleiteten Typ verwendet wird. (Wenn über die Schnittstelle genannt.)

Aus dem Bereich 13.4.4 der C # 3.0-Spezifikation:

  

Schnittstellenzuordnung für eine Klasse oder   struct C findet eine Implementierung für   jedes Mitglied jeder Schnittstelle   in der Basisklasse Liste von C spezifiziert   Die Implementierung eines bestimmten   Schnittstelle Mitglied I.M, wobei I die   Schnittstelle in der das Element M ist   erklärte, wird bestimmt durch die Prüfung   jede Klasse oder Struktur S, beginnend mit   C und Wiederholen für jeden aufeinanderfolgende   Basisklasse von C, bis eine Übereinstimmung ist,   zu finden:

     
      
  • Wenn S eine Erklärung enthält   ein expliziten Schnittstellenelement   Implementierung, die ich und M übereinstimmt,   dann ist dieses Mitglied die Umsetzung   von I.M.
  •   
  • Andernfalls, wenn S eine Deklaration eines nicht-statischen öffentlichen Mitglied enthält, die M übereinstimmt, dann ist dieses Mitglied die Implementierung von IM Wenn mehr als ein Mitglied übereinstimmt, ist es nicht spezifiziert ist, welches Mitglied die Implementierung von IM nur Diese Situation ist kann auftreten, wenn S ein konstruierter Typ ist, wo die beiden Elemente, wie in der gattungsbildenden Art haben unterschiedliche Signaturen erklärt, aber die Art Argumente machen ihre Unterschrift identisch.
  •   

Andere Tipps

(A) a tut nichts. Die Referenz wird bereits erklärt, wie eine, so dass es zu einem Casting keine Wirkung hat.

Auch wenn Ihre Referenz als A deklariert wird, das Objekt, das es sich bezieht, ist vom Typ B. Wenn Sie dieses Objekt zu IHello werfen, wird ein Aufruf Hallo () Objekt B ausdrückliche Umsetzung Hallo nennen.

Der Ausgang ist genau wie erwartet.

Nein, wenn Sie einen neue Methode (ToString) erstellen, ist es nicht virtuell. New bedeutet nur, dass Sie es nicht stören die Version in der Basisklasse „versteckt“ - also, wenn Sie es mit einer Referenz nennen, die Sie auf einen bestimmten Typen geworfen haben (A), führt sie die Methode in der Klasse A, unabhängig davon, die tatsächliche Art des Objekts Sie anrufen. (Das heißt Sie genannt A.ToString (), so wird sie ausgeführt A.ToString ())

Wenn Sie eine virtuelle Methode erstellen, dann, unabhängig davon, welche Art werfen Sie den Verweis auf, die Umsetzung von dem tatsächlichen Typ des Objekts verwendet wird (dh Sie ein B erstellt, so dass, wenn Sie angerufen (was auch immer das Objekt) .Hello, es genannt B.Hello)

Der entscheidende Unterschied besteht darin, dass ein Anruf virtuellen und der andere nicht.

Nein, sollte es nicht.

Wenn Sie eine virtuelle Methode aufrufen, ist es egal, was die Art der Referenz. Die Methode, die aufgerufen wird, um den tatsächlichen Typ des Objektes bestimmt wird, nicht der Typ der Referenz.

Wie Sie eine Instanz der Klasse B erstellen, ist die tatsächliche Art des Objekts B. Der Grund, dass es "This is class A." druckt ist, dass Sie nicht die ToString Methode in der Klasse B außer Kraft gesetzt haben, haben Sie es mit dem new Schlüsselwort beschatten. Deshalb ist die B Klasse hat zwei ToString Methoden, eines aus der Klasse A und einem ererbten, die es Schatten. Wenn Sie eine A Referenz verwenden, um die ToString Methode aufrufen, wird die geerbte Methode genannt, aber wenn Sie eine B Referenz verwendet hätte, es zu nennen, würde die Abschattung Methode aufgerufen werden, "This is class B." auszudrucken.

Auch wenn Sie die ToString Methode in der Klasse B außer Kraft setzen, anstatt sie zu beschatten, wäre es "This is class B." auszudrucken unabhängig von der Art der Referenz.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top