niedergeschlagen und ausgestoßen


87

Ich bin neu in C # (und OOP ). Wenn ich Code wie den folgenden habe:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

Frage 1 : Wenn ich einen anderen Code habe, der dies tut:

   Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

Hier Employeeist ein Manager, aber wenn ich es so auf ein Employeebesetze, bedeutet das, dass ich es übertrage?

Frage 2 :

Wenn ich mehrere EmployeeKlassenobjekte habe und einige, aber nicht alle von ihnen sind Manager, wie kann ich sie nach Möglichkeit herunterwerfen?


6
Upcasting kann ohne explizite Besetzung erfolgen. Sollte also Employee emp= mgr;ausreichen.
Küssen Sie meine Achselhöhle

Antworten:


93
  1. Das ist richtig. Wenn Sie dies tun, wandeln Sie es in ein employeeObjekt um, sodass Sie auf nichts Manager-spezifisches zugreifen können.

  2. Beim Downcasting nehmen Sie eine Basisklasse und versuchen dann, sie in eine spezifischere Klasse umzuwandeln. Dies kann mit is und einer expliziten Besetzung wie dieser erreicht werden:

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

oder mit dem asBetreiber wie folgt:

Manager m = (employee as Manager);
if (m != null)
{
    //do something with it
}

Wenn etwas unklar ist, werde ich es gerne korrigieren!


Ich brauche ein Beispiel, um zu wissen, was Downcasting ist.
user184805

4
Vermeiden Sie es, etablierte Begriffe neu zu definieren: „Boxen“ bedeutet im Kontext von OOP und C # etwas ganz anderes (= Einschließen eines Werttypobjekts in eine Referenz). Außerdem könnte (und sollte) Ihr Beispiel den asOperator anstelle von verwenden is, gefolgt von einer Besetzung.
Konrad Rudolph

2
Ich stehe im ersten Punkt korrigiert und habe die zweite Hälfte meiner Antwort geändert, um beide Möglichkeiten aufzuzeigen.
RCIX

2
Ihre erste Aussage ("... das Casting [einer Instanz der Manager-Klasse] in ein" Mitarbeiter "-Objekt [..] bedeutet, dass Sie auf nichts Manager-spezifisches zugreifen können") ist nicht vollständig korrekt. Wenn im Beispiel von OP der Mitarbeiter ein virtuelles Mitglied hat, das im Manager überschrieben wird, ruft die CLR die Manager-Implementierung ungeachtet der Besetzung auf. Aus dem MSDN-Artikel zum Polymorphismus in C #: "Wenn eine abgeleitete Klasse ein virtuelles Mitglied überschreibt, wird dieses Mitglied auch dann aufgerufen, wenn auf eine Instanz dieser Klasse als Instanz der Basisklasse zugegriffen wird." Das von MSDN bereitgestellte Beispiel ist nahezu identisch.
Antony

49

Das Upcasting (Verwenden (Employee)someInstance) ist im Allgemeinen einfach, da der Compiler Ihnen beim Kompilieren mitteilen kann, ob ein Typ von einem anderen abgeleitet ist.

Das Downcasting muss jedoch im Allgemeinen zur Laufzeit erfolgen, da der Compiler möglicherweise nicht immer weiß, ob die betreffende Instanz vom angegebenen Typ ist. C # bietet zwei Betreiber für diese - ist , was Sie , wenn die niedergeschlagenen Werke erzählt, und wahr / falsch zurück. Und wie versucht, die Umwandlung durchzuführen und gibt den richtigen Typ zurück, wenn möglich, oder null, wenn nicht.

So testen Sie, ob ein Mitarbeiter ein Manager ist:

Employee m = new Manager();
Employee e = new Employee();

if(m is Manager) Console.WriteLine("m is a manager");
if(e is Manager) Console.WriteLine("e is a manager");

Sie können dies auch verwenden

Employee someEmployee = e  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");

Employee someEmployee = m  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");

11
  • Upcasting ist eine Operation, die eine Basisklassenreferenz aus einer Unterklassenreferenz erstellt. (Unterklasse -> Oberklasse) (dh Manager -> Mitarbeiter)
  • Downcasting ist eine Operation, die eine Unterklassenreferenz aus einer Basisklassenreferenz erstellt. (Oberklasse -> Unterklasse) (dh Mitarbeiter -> Manager)

In deinem Fall

Employee emp = (Employee)mgr; //mgr is Manager

Sie machen eine Übertragung.

Ein Upcast ist immer erfolgreich, im Gegensatz zu einem Downcast, für den eine explizite Umwandlung erforderlich ist, da er zur Laufzeit möglicherweise fehlschlagen kann ( InvalidCastException ).

C # bietet zwei Operatoren, um zu vermeiden, dass diese Ausnahme ausgelöst wird:

Ab:

Employee e = new Employee();

Zuerst:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown

Zweite:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

Warnung : Wenn Sie einen Upcast ausführen, können Sie nur auf die Methoden, Eigenschaften usw. der Oberklasse zugreifen.


6

Wenn Sie jedes Employee-Objekt überprüfen müssen, ob es sich um ein Manager-Objekt handelt, verwenden Sie die OfType-Methode:

List<Employee> employees = new List<Employee>();

//Code to add some Employee or Manager objects..

var onlyManagers = employees.OfType<Manager>();

foreach (Manager m in onlyManagers) {
  // Do Manager specific thing..
}

2

Antwort 1: Ja, es heißt Upcasting, aber die Art und Weise, wie Sie es tun, ist nicht modern. Upcasting kann implizit durchgeführt werden, Sie benötigen keine Konvertierung. Schreiben Sie einfach Employee emp = mgr; ist genug für die Übertragung.

Antwort 2: Wenn Sie ein Objekt der Manager-Klasse erstellen, können wir sagen, dass der Manager ein Mitarbeiter ist. Weil Klasse Manager: Mitarbeiter stellen Is-A - Beziehung zwischen Klasse Employee und Manager - Klasse. Wir können also sagen, dass jeder Manager ein Mitarbeiter ist.

Wenn wir jedoch ein Objekt der Employee-Klasse erstellen, können wir nicht sagen, dass dieser Mitarbeiter Manager ist, da die Klasse Employee eine Klasse ist, die keine andere Klasse erbt. Sie können dieses Employee Class-Objekt also nicht direkt auf das Manager Class-Objekt übertragen.

Die Antwort lautet also: Wenn Sie vom Employee Class-Objekt zum Manager Class-Objekt downcasten möchten, müssen Sie zuerst ein Objekt der Manager Class haben, dann können Sie es upcasten und dann können Sie es downcasten.


-1

Upcasting und Downcasting:

Upcasting: Casting von der abgeleiteten Klasse zur Basisklasse Downcasting: Casting von der Basisklasse zur abgeleiteten Klasse

Lassen Sie uns das gleiche als Beispiel verstehen:

Betrachten Sie zwei Klassen Shape als meine übergeordnete Klasse und Circle als abgeleitete Klasse, die wie folgt definiert sind:

class Shape
{
    public int Width { get; set; }
    public int Height { get; set; }
}

class Circle : Shape
{
    public int Radius { get; set; }
    public bool FillColor { get; set; }
}

Upcasting:

Form s = neue Form ();

Kreis c = s;

Sowohl c als auch s verweisen auf denselben Speicherort, aber beide haben unterschiedliche Ansichten. Mit der Referenz "c" können Sie auf alle Eigenschaften der Basisklasse und der abgeleiteten Klasse zugreifen, aber mit der Referenz "s" können Sie auf Eigenschaften zugreifen der einzigen Elternklasse.

Ein praktisches Beispiel für Upcasting ist die Stream-Klasse, die eine Grundklasse aller Arten von Stream-Readern des .net-Frameworks darstellt:

StreamReader reader = neuer StreamReader (neuer FileStreamReader ());

Hier wird FileStreamReader () auf streadm reder übertragen.

Downcasting:

Form s = neuer Kreis (); Wie oben erläutert, ist die Ansicht von s der einzige Elternteil. Um sie sowohl für Eltern als auch für ein Kind zu erstellen, müssen wir sie herunterstoßen

var c = (Kreis) s;

Das praktische Beispiel für Downcasting ist die Button-Klasse von WPF.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.