2013-04-08 11 views
8

Il tipo di esecuzione di tutte le istanze di chiamata è D conseguenza, tutte le invocazioni di F() dovrebbe essere il metodo F() dichiarata in D.L'uscita di questo blocco di codice non ha senso mi

using System; 
class A 
{ 
    public virtual void F() { Console.WriteLine("A.F"); } 
} 
class B: A 
{ 
    public override void F() { Console.WriteLine("B.F"); } 
} 
class C: B 
{ 
    new public virtual void F() { Console.WriteLine("C.F"); } 
} 
class D: C 
{ 
    public override void F() { Console.WriteLine("D.F"); } 
} 
class Test 
{ 
    static void Main() { 
     D d = new D(); 
     A a = d; 
     B b = d; 
     C c = d; 
     a.F(); 
     b.F(); 
     c.F(); 
     d.F(); 
    } 
} 

l'output è:

B.F 
B.F 
D.F 
D.F 

non dovrebbe essere l'output:

D.F 
D.F 
D.F 
D.F 
+0

È necessario modificare il titolo della domanda per gran parte del problema – MarcinJuraszek

risposta

1

si utilizza new public virtual void F() in classe C: B. Significa che il F() nella classe C e F() nella classe B sono metodi diversi.

Quindi, quando si sostituisce C in classe D, il metodo F() in classe D viene sovrascritto dalla classe C, non B.

Un altro esempio ovvio può essere del tipo:

C c = new C(); 
    B b = c; 
    b.F(); 
    c.F(); 
+0

Ma il tipo di runtime di tutte le istanze di chiamata è D, il che significa che l'implementazione di F() in D è quella invocata. –

+0

Non esattamente fino a quando il metodo 'F()' non viene sovrascritto. Se usi 'new', invece, sarà gestito come un nuovo metodo, non sovrascritto. – Fendy

+0

Capito! E poiché l'implementazione più vicina al tipo di chiamante in fase di esecuzione, in questo caso la F() in B per a.F(); b.F(); e F() in D per c.F(); d.F() ;, viene chiamato. –

7

Versioning with the Override and New Keywords (C# Programming Guide)

Se il metodo nella classe derivata è preceduta con la nuova parola chiave, il metodo è definito come essendo indipendente dalla metodo nella classe di base.

Così you'r F metodi da A e B non sono collegato con questi da C e D, ed è per questo che si ottiene ciò che si ottiene.

Al runtime CLR cerca l'implementazione del metodo virtual che dovrebbe essere utilizzata a partire dal tipo in cui le variabili sono dichiarate in modo da poterlo digitare. Per a.F() e b.F() si arresta sulla dichiarazione B.F(), perché C.F() è un metodo diverso (a causa di new).

1

Non dovrebbe ...

A a = d; 

Questo significa che si sta creando una classe di tipo A. E poiché stai esplicitamente ignorando il metodo correlato nella classe B; A utilizza il metodo nella classe B.

D'altro canto, in questa linea;

new public virtual void F() { Console.WriteLine("C.F"); } 

si dichiara che non utilizzerà il metodo F() dalla base utilizzando la parola chiave new.

Se tu avessi sovresposta il metodo F() in D e C classi, tutte le istanze avrebbero chiamato il metodo F() dichiarato nella D classe.

Problemi correlati