Laden...

Wie kann ich ein vererbtes Objekt in ein Objekt der Basisklasse casten?

Erstellt von kom2006 vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.186 Views
Thema geschlossen
K
kom2006 Themenstarter:in
110 Beiträge seit 2007
vor 11 Jahren
Wie kann ich ein vererbtes Objekt in ein Objekt der Basisklasse casten?

Hallo zusammen,

ich habe gerade folgendes Problem:

Basisklasse A ist eine Konfigurationsklasse für Objekte in meinem Programm, die ich per Serialize und Deserialze laden und speichern kann. Es gibt davon mehrere Objekte im Programm zur Laufzeit.

Da ich im Programm während der Laufzeit zusätzliche Eigenschaften für ein Objekt benötige, habe ich dafür eine Klasse von A abgeleitet, nennen wir sie B und entsprechend erweitert - funktioniert auch problemlos.

Während der Laufzeit kann man die Konfiguration einen Objekts ändern und diese möchte ich dann abspeichern. Ich wollte dazu auf die entsprechende Funktion der Basisklasse von B zugreifen, doch das gibt Probleme 😉

Rufe ich die Serialize-Funktion aus dem Objekt B auf, dann schlägt dies fehl, da der Serializer aus der Basisklasse mit den erweiterten Eigenschaften von B nichts anfangen kann. Das verstehe ich.

Was ich nicht verstehe ist, warum folgender Ansatz fehlschlägt:


A tempObjektA = new A();
tempObjektA = B;

bzw.

A tempObjektA = (A)B;

In beiden Fällen ist tempObjektA identisch mit B, also inklusive der erweiterten Eigenschaften.

Ich möchte beim Zurückcasten aber erreichen, dass tempObjektA nur die Eigenschaften der Basisklase A von B hat, um dann die Serialize-Funktion fehlerfrei aufrufen zu können. Ich könnte die Laufzeit-Eigenschaften von B natürlich in A definieren, aber diese haben in der Konfigurationsdatei nichts zu suchen.

Ferner kann ich natürlich die Eigenschaften von A einzeln aus B zuweisen in der Form


A.Prop1 = B.Prop1;
A.Prop2 = B.Prop2;
usw.

aber das muss doch auch einfacher gehen.

Grüße

D
615 Beiträge seit 2009
vor 11 Jahren

Hallo Kom2006

Also Dein Problem ist also das Serializen. Selbst wenn du eine Kaffeemaschine in ein Elektrogerät castest, bleibt es eine Kaffeemaschine (nur halt generalisiert).

Dem Serializer musst du "erklären" das Elektrogerät auch serialisiert werden soll, dafür gibts 2 Varianten.

1.


[Serializable()]
[XmlInclude(typeof(KaffeeMaschine))]
public class Elektrogerät

Die Serialize Methode hat eine Überladung wo du solche Typen als Array mitgeben kannst.

Wenn du Eigenschaften ausblenden willst, kannst du dies so erreichen:


[XmlIgnore]
public bool MaschineHatStrom{get;set;} 

(Um dein Ziel zu erreichen also :

  1. Include XML Type
  2. Exclude all Properties in Class B)

Beste Grüsse

Diräkt

Edit: Bedürfniss für Exclude entdeckt und hinzugefügt

K
kom2006 Themenstarter:in
110 Beiträge seit 2007
vor 11 Jahren

Hallo Diräkt,

ich weiss jetzt gerade nicht, ob wir aneinander vorbei sprechen.

Ich möchte B nie speichern (serialisieren) und die zusätzlichen Eigenschaften von B sollen auch nie gespeichert werden (da sind reine Runtimeinformationen in den zusätzlichen Eigenschaften drin).

Deshalb möchte ich aus B ja wieder A machen, damit beim Speichern tatsächlich auch nur die Konfigurations-Eigenschaften (in A und B vorhanden) gespeichert werden.

D
615 Beiträge seit 2009
vor 11 Jahren

Hallo Kom2006

Du erreichst dies indem du alle Eigenschaften von B auf XML Ignore setzt. (Attribut hinzufügen)
Somit sieht dann B gleich aus wie A wenn es serialisiert wird.

Damit die Serialisierung überhaupt klaptt (Vererbung etc.) musst du aber entweder im Serialize-Konstruktor den Typ mitgeben oder die Klasse mit XmlInclude versehen.

Beste Grüsse

Diräkt

K
kom2006 Themenstarter:in
110 Beiträge seit 2007
vor 11 Jahren

Genau so funktioniert es, vielen Dank!

Hinweis von herbivore vor 11 Jahren

Ein Objekt behält den bei der Erzeugung vergebenen Typ sein ganzes Leben lang. Er kann nicht geändert werden. Um ein Objekt der Unterklasse an einer Variable der Oberklasse zuzuweisen, muss man nicht mal casten. Selbst wenn man castet, ändert sich bei Referenztypen nie der Typ des Objekts selbst (es sei denn, es ist ausdrücklich eine Umwandlung definiert, aber dann wird von dieser ein neues Objekt erstellt). Mit diesem Grundlagenwissen, hätten du dir alles selbst erklären können.

Und die die Frage, was denn nun bei der Xml-Serialisierung serialisiert wird und wie man das beeinflussen kann (XmlIgnore), kann man der einführenden Beschreibung der Xml-Serialisierung in der MSDN Doku nachlesen: Einführung in die XML-Serialisierung, Unterabschnitt Steuern der XML-Serialisierung mit Attributen.

Bitte beachte daher [Hinweis] Wie poste ich richtig? Punkt 1.1.1 und 1.1.

Thema geschlossen