Differenza tra shadowing e override in C #?

Qual è la differenza tra lo shadowing e l’ override di un metodo in C #?

Bene ereditarietà …

supponi di avere queste classi:

class A { public int Foo(){ return 5;} public virtual int Bar(){return 5;} } class B : A{ public new int Foo() { return 1;} //shadow public override int Bar() {return 1;} //override } 

allora quando chiami questo:

 A clA = new A(); B clB = new B(); Console.WriteLine(clA.Foo()); // output 5 Console.WriteLine(clA.Bar()); // output 5 Console.WriteLine(clB.Foo()); // output 1 Console.WriteLine(clB.Bar()); // output 1 //now let's cast B to an A class Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow Console.WriteLine(((A)clB).Bar()); // output 1 

Supponiamo che tu abbia una class base e tu usi la class base in tutto il tuo codice invece delle classi ereditate, e tu usi shadow, restituirà i valori restituiti dalla class base invece di seguire l'albero ereditario del tipo reale dell'object.

Esegui il codice qui

Spero di aver senso 🙂

Shadowing è in realtà VB parlance per quello che vorremmo vedere come nascosto in C #.

Spesso nascondendo (shadowing in VB) e override sono mostrati come in risposta da Stormenet .

Viene mostrato che un metodo virtuale è sovrascritto da una sottoclass e le chiamate a quel metodo anche sul tipo di super-class o dal codice interno della super-class chiameranno l’implementazione sostitutiva dalla sottoclass.

Quindi viene mostrato un metodo concreto (uno non contrassegnato come virtuale o astratto) nascosto usando la new parola chiave quando si definisce un metodo con una firma identica sulla sottoclass. In questo caso, quando il metodo viene chiamato sul tipo di super class, viene utilizzata l’implementazione originale, la nuova implementazione è disponibile solo nella sottoclass.

Tuttavia, ciò che spesso manca è che è anche ansible hide un metodo virtuale.

 class A { public virtual void DoStuff() { // original implementation } } class B : A { public new void DoStuff() { //new implementation } } B b = new B(); A a = b; b.DoStuff(); //calls new implementation a.DoStuff(); //calls original implementation. 

Nota nell’esempio precedente, DoStuff diventa concreto e non può essere annullato. Tuttavia è anche ansible utilizzare sia le parole chiave virtual che new insieme.

 class A { public virtual void DoStuff() { // original implementation } } class B : A { public new virtual void DoStuff() { //new implementation } } class C : B { public override void DoStuff() { //replacement implementation } } C c = new C(); B b = c; A a = b; c.DoStuff(); //calls replacement implementation b.DoStuff(); //calls replacement implementation a.DoStuff(); //calls original implementation. 

Si noti che nonostante tutti i metodi coinvolti siano virtuali, l’override su C non influenza il metodo virtuale su A poiché l’uso di new in B nasconde l’implementazione A.

Modifica: è stato notato nei commenti a questa risposta che quanto sopra può essere pericoloso o almeno non particolarmente utile. Direi di sì, può essere pericoloso e starei là fuori se fosse del tutto utile.

In particolare, potresti entrare in tutti i tipi di problemi se modifichi anche i modificatori di accessibilità. Per esempio:-

 public class Foo { internal Foo() { } protected virtual string Thing() { return "foo"; } } public class Bar : Foo { internal new string Thing() { return "bar"; } } 

Ad un erede esterno di Bar , l’implementazione di Thing () di Foo rimane accessibile e superabile. Tutto legale e spiegabile secondo le regole di tipo .NET, senza dubbio non del tutto ingegnoso.

Ho postato questa risposta per approfondire la comprensione di come le cose funzionano non come un suggerimento di tecniche che possono essere utilizzate liberamente.

Penso che la differenza principale sia che con shadowing stai essenzialmente riutilizzando il nome e ignori semplicemente l’uso della superclass. Con l’override, stai cambiando l’implementazione, ma non l’accessibilità e la firma (ad es. Tipi di parametri e resi). Vedi http://www.geekinterview.com/question_details/19331 .

Shadowing è un concetto VB.NET. In C #, Shadowing è noto come Hiding. Nasconde il metodo della class derivata. È realizzato utilizzando la parola chiave “nuova”.

La parola chiave Override viene utilizzata per fornire un’implementazione completamente nuova di un metodo della class base (contrassegnato come “Virtuale”) nella class derivata.

Fondamentalmente se hai qualcosa come sotto,

 Class A { } Class B:A { } A a = new B(); 

Qualsiasi metodo chiamato sull’object ‘a’ sarà fatto sul tipo di ‘a’ (Qui il tipo è ‘A’) Ma se si implementa lo stesso metodo in class B che è già presente in Classe A, il compilatore darti un avvertimento per usare una parola chiave “Nuovo”. Se si utilizza “Nuovo”, l’avviso scomparirà. Oltre a questo non vi è alcuna differenza tra l’uso di “Nuovo” o il non utilizzo nella class ereditata.

In alcune situazioni potrebbe essere necessario chiamare un metodo della class di riferimento che l’istanza particolare contiene in quel momento invece di chiamare un metodo sul tipo di object. Nel caso precedente il riferimento che contiene è ‘B’, ma il tipo è ‘A’. Quindi, se si desidera che la chiamata al metodo venga eseguita su “B”, utilizzare Virtual e override per ottenere ciò.

Spero che questo ti aiuti…

Daniel Sandeep.