Question

Sortie: B-> Bonjour! de explicite.

Faut-il pas: A> Bonjour! de explicite.

Pourquoi pas explicite coulé (IHello) un appel IHello.Hello () de la classe 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();
    }
}
Était-ce utile?

La solution

Non, il ne devrait pas.

L'appel à Hello est équivalente à la en commentaire un - la route pour obtenir un IHello n'a pas d'importance (à moins qu'il ne nécessite la vérification ou la conversion d'exécution en temps); le type de compilation est juste IHello soit, et le mappage d'interface est la même mais vous y arriver.

Lorsqu'une interface est explicitement mis en œuvre plus d'une fois dans la hiérarchie de type, la mise en œuvre dans le type le plus dérivé est utilisé. (Lorsqu'il est appelé par l'intermédiaire de l'interface.)

De la section 13.4.4 du C # 3.0 Spécification:

  

mappage d'interface pour une classe ou   struct C localise une mise en œuvre   chaque élément de chaque interface   spécifié dans la liste de classe de base de C.   La mise en œuvre d'un particulier   membre de l'interface i.m., où I est la   une interface dans laquelle l'élément M est   déclaré, est déterminée en examinant   chaque classe ou struct S, en commençant par   C et en répétant pour chaque successive   la classe de base de C, jusqu'à ce qu'une correspondance est   situé:

     
      
  • Si S contient une déclaration   d'un membre d'interface explicite   la mise en œuvre qui correspond à I et M,   alors ce membre est la mise en œuvre   de i.m..
  •   
  • Dans le cas contraire, si S contient une déclaration d'un membre du public non-statique qui correspond à M, alors ce membre est la mise en œuvre de la messagerie instantanée Si plus d'un membre correspondant, il est non précisé quel membre est la mise en œuvre de la GI Cette situation ne peut se produire si S est un type construit où les deux membres comme déclarées dans le type générique ont des signatures différentes, mais les arguments de type font leurs signatures identiques.
  •   

Autres conseils

(A) ne fait rien. La référence est déjà déclarée comme si la coulée à A aura aucun effet.

Même si votre référence est déclarée comme A, l'objet auquel il se réfère à est de type B. Si vous lancez cet objet à IHello, un appel à Bonjour () appellera la mise en œuvre explicite de l'objet B Bonjour.

La sortie est exactement comme prévu.

Non, lorsque vous créez un nouveau méthode (ToString), il est virtuel. Nouveau signifie simplement que vous ne me dérange pas « cacher » la version de la classe de base - donc si vous l'appelez avec une référence que vous avez jeté à un type spécifique (A), il exécute la méthode dans la classe A, quel que soit le type réel de l'objet que vous appelez. (I.e. que vous avez appelé A.ToString () il exécuté A.ToString ())

Lorsque vous créez un virtuel méthode , puis peu importe le type que vous lancez la référence, la mise en œuvre du type réel de l'objet est utilisé (par exemple vous avez créé un B, alors quand vous avez appelé (quel que soit l'objet est) .Bonjour, il a appelé b.hello)

La différence fondamentale est que l'un appel virtuel et l'autre pas.

Non, il ne devrait pas.

Lorsque vous appelez une méthode virtuelle, peu importe ce que le type de référence est. La méthode qui est appelée est déterminé par le type réel de l'objet, et non le type de la référence.

Lorsque vous créez une instance de la classe B, le type réel de l'objet est B. La raison pour laquelle il imprime "This is class A." est que vous ne l'avez pas la méthode de substitution ToString dans la B de classe, vous avez ombré à l'aide du mot-clé new. Par conséquent, la classe B a deux méthodes de ToString, héritée de la A de classe et qui ombres elle. Si vous utilisez une référence A pour appeler la méthode ToString, la méthode héritée est appelée, mais si vous avez utilisé une référence B pour l'appeler, la méthode de shadowing serait appelé, imprimer "This is class B.".

Aussi, si vous substituez la méthode de ToString dans la B de classe au lieu de shadowing, il serait imprimer "This is class B." quel que soit le type de la référence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top