2016-11-09 2 views
-2

ich vor kurzem über Kovarianz und Kontra lesen - wenig Codebeispiel unten:Kontra in der Praxis - C#

public class BaseClass{ 
    public int x = 1; 

    public static void print(BaseClass objClass) 
    { 
     Console.WriteLine(objClass.GetType().Name + " " + objClass.x); 
    } 
} 

public class DerivedClass : BaseClass{ 
    public int x = 2; 
} 

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     BaseClass bC = new BaseClass(); 
     DerivedClass dC = new DerivedClass(); 

     BaseClass.print(bC); //DerivedClass 1 
     DerivedClass.print(bC); //DerivedClass 1 
     BaseClass.print(dC); //DerivedClass 1 
     DerivedClass.print(dC); //DerivedClass 1 
    } 
} 

Meine Frage ist - was uns Kontra in der Praxis geben? Ich weiß, dass ich das Objekt der DerivedClass als Argument in die BaseClass-Methode übergeben kann (wobei der Parameter der BaseClass-Typ ist), aber was sind die Vorteile einer solchen Operation? Und warum, wenn ich das DerivedClass-Objekt übergebe, gibt es den Wert von x in BaseClass zurück?

Vielleicht ist dies ein schlechtes Beispiel für die Vorteile der Kontravarianz zu erklären, dann wäre ich dankbar für ein anderes Beispiel.

+6

Dies verwendet keine Kontravarianz überall. – Lee

+0

Wow - so gibt es irreführende Tutorials im Internet;) Aber wie auch immer - kann mir jemand erklären, warum wenn ich das DerivedClass-Objekt übergebe, gibt es mir den Wert von x in BaseClass zurück? Wenn es nichts ändert, warum können wir das tun? PS. Sinatr - Danke für diesen Link – Hadrian

+1

Sie verwechseln Varianz mit Vererbung/Polymorphie. –

Antwort

1

Warum, wenn ich abgeleiteten Klassenobjekt übergeben, gibt es mir den Wert von x in BaseClass?

Sie sind versteckt das Feld in der abgeleiteten Klasse. In der Tat DerivedClass hat zweix Felder - eine aus der Basisklasse, eine aus der abgeleiteten Klasse. Da der Parameter print vom Typ BaseClass ist, bindet der Compiler objClass.x an das Feld in der Basisklasse.

Wenn Sie stattdessen eine virtuelle Eigenschaft haben, und eine Überschreibung:

public class BaseClass{ 
    public virtual int x {get {return 1;}} 

    public static void print(BaseClass objClass) 
    { 
     Console.WriteLine(objClass.GetType().Name + " " + objClass.x); 
    } 
} 

public class DerivedClass : BaseClass{ 
    public override int x {get {return 2;}} 
} 

Oder nur das Basisfeld auf einen anderen Wert in der abgeleiteten Klasse festgelegt:

public class DerivedClass : BaseClass{ 
    public DerivedClass() {x = 2;} 
} 

würden Sie sehen die Ergebnisse, die Sie erwarten.

+0

Vielen Dank für hilfreiche Erklärung! Jetzt ist es ziemlich klar für mich! – Hadrian