![]() |
TObjectList unterschiedliche Objekte erkennen?
Hallo,
ich speichere in einer TObjectList unterschiedliche Objekte ab. Meine Frage lautet nun, wie kann ich beim auslesen der Objekte erkennen, um welches Objekt es sich handelt? Die Objekte, welche ich in der List ablege, sind alle von einem anderen Objekt (TAuto) abgeleitet. Ich habe folgendese probiert:
Code:
Funktioniert aber nicht.
for i := 0 to ObjectList.Count - 1 do
begin Auto := TAuto(Result.Items[i]); if (Auto is TCabrio) then ShowMessage('Es ist ein Cabrio'); if (Auto is TCoupe) then ShowMessage('Es ist ein Coupe'); end; Wäre nett, wenn mir jemand bitte helfen könnte. Bin wohl noch nicht ganz ausgeschlafen ;). Vielen Dank. |
AW: TObjectList unterschiedliche Objekte erkennen?
Was bedeutet "funktioniert nicht"? Eigentlich sollte es, wenn ich nichts übersehen habe und die Daten auch wirklich stimmen.
|
AW: TObjectList unterschiedliche Objekte erkennen?
Zitat:
Delphi-Quellcode:
vs
ObjectList
Delphi-Quellcode:
?
Result
|
AW: TObjectList unterschiedliche Objekte erkennen?
Das heißt, dass er mir nicht erkennt, um welche Klasse es sich handelt. Obwohl ich in meine ObjectList ein TCabrio eingetragen habe, erkennt er mir hier
Code:
nicht, dass es sich um ein TCabrio Objekt handelt.
if (Auto is TCabrio) then
ShowMessage('Es ist ein Cabrio'); @Sir Rufo: Sorry, das heißt natürlich nicht Result sondern Objectlist. |
AW: TObjectList unterschiedliche Objekte erkennen?
Na gut, so gesehen. Auf jeden Fall zu wenig Infos.
|
AW: TObjectList unterschiedliche Objekte erkennen?
Zitat:
|
AW: TObjectList unterschiedliche Objekte erkennen?
Und zeigen Result und ObjectList auf dasselbe Objekt? Diese Frage von Sir Rufo scheint das Entscheidende zu sein.
|
AW: TObjectList unterschiedliche Objekte erkennen?
Ok, ich versuche es beispielhaft zu erklären.
Habe folgende Klassen: TAuto:
Code:
TCabrio:
TAuto = class(TObject)
private FHersteller: string; published property Hersteller: string read FHersteller write FHersteller; end;
Code:
TCoupe:
TCabrio = class(TAuto)
private FSitze: integer; published property FSitze: string read FSitze write FSitze; end;
Code:
TCoupe= class(TAuto)
private FSitze: integer; published property FSitze: string read FSitze write FSitze; end; Nun speichere ich Objekte in meiner TObjectlist:
Code:
Und hier möchte ich auselesen, um welches Objekt es sich handelt:
var: AutoListe: TObjectList;
Cabrio: TCabrio; Coupe: TCoupe: Auto: TAuto; AutoListe := TObjectList.Create; Auto := TAuto.Create; Auto.FHersteller := 'BMW'; Coupe:= TCoupe(Auto); Coupe.FSitze := 4; AutoListe.Add(Coupe); Auto := TAuto.Create; Auto.FHersteller := 'VW'; Cabrio:= TCabrio(Auto); Cabrio.FSitze := 2; AutoListe.Add(Cabrio);
Code:
Aber es wird mir keine ShowMessage-Box erzeugt, somit erkennt er mir auch nicht mein Objekt.
for i := 0 to ObjectList.Count - 1 do
begin Auto := TAuto(ObjectList.Items[i]); if (Auto is TCabrio) then ShowMessage('Es ist ein Cabrio'); if (Auto is TCoupe) then ShowMessage('Es ist ein Coupe'); end; |
AW: TObjectList unterschiedliche Objekte erkennen?
Dein Problem liegt hier:
Zitat:
Delphi-Quellcode:
Dies ist beispielhaft für jede Unterklasse von TAuto. Dann funktioniert es auch mit
Coupe := TCoupe.Create;
Coupe.FHersteller := 'BMW'; Coupe.FSitze := 4; AutoListe.Add(Coupe);
Delphi-Quellcode:
if Objectlist[i] is TCoupe then...
|
AW: TObjectList unterschiedliche Objekte erkennen?
Du erstellst die Objekte falsch. Versuch es mal so:
Delphi-Quellcode:
var: AutoListe: TObjectList;
Cabrio: TCabrio; Coupe: TCoupe: Auto: TAuto; AutoListe := TObjectList.Create; Coupe:= TCoupe.Create; Coupe.Hersteller := 'BMW'; Coupe.Sitze := 4; AutoListe.Add(Coupe); Cabrio := TCabrio.Create; Cabrio.Hersteller := 'VW'; Cabrio.Sitze := 2; AutoListe.Add(Cabrio); |
AW: TObjectList unterschiedliche Objekte erkennen?
Hallo,
Wenn du eine Object vom Typ Caprio tatsächlich mit Create erzeugen würdest, dann könnte dein Code schon funktionieren. Aber aus irgenteinem Grund erzeugst du immer Auto und behauptest über einen Cast das es ein Caprio ist bevor du Werte zuweist. das kann der is Operator aber niemals auflösen. mfg DerDan |
AW: TObjectList unterschiedliche Objekte erkennen?
Du castest ja das Auto nur als Cabrio. Sein tut's immer noch ein TAuto ...So wird ein Schuh draus:
Delphi-Quellcode:
Edit: ups, zu spät.
procedure TForm1.Button3Click(Sender: TObject);
var AutoListe: TObjectList; Cabrio : TCabrio; Coupe : TCoupe; Auto : TAuto; ListenAuto : TObject; i : integer; begin AutoListe := TObjectList.Create; Auto := TAuto.Create; Auto.FHersteller := 'BMW'; Coupe:= TCoupe(Auto); Coupe.FSitze := 4; AutoListe.Add(Coupe); Auto := TAuto.Create; Auto.FHersteller := 'VW'; Cabrio:= TCabrio.Create; Cabrio.FSitze := 2; AutoListe.Add(Cabrio); for i := 0 to AutoListe.Count - 1 do begin ListenAuto := AutoListe.Items[i]; if (ListenAuto is TCabrio) then begin ShowMessage('Es ist ein Cabrio'); end else if (ListenAuto is TCoupe) then begin ShowMessage('Es ist ein Coupe'); end else begin ShowMessage(Auto.ClassName); end; end; end; |
AW: TObjectList unterschiedliche Objekte erkennen?
Alles klar, vielen Dank für eure zahlreichen Antworten. So funktioniert es.
Wollte mir das belegen der Vater-Attribute immer sparen - da diese für jedes abgeleitete Kind ja immer gleich sind - und bin deshalb diesen Weg gegangen. Aber dann belege ich die Attribute halt für jedes Kind. Vielen Dank nochmal Gruß mc |
AW: TObjectList unterschiedliche Objekte erkennen?
Musst Du doch gar nicht.
|
AW: TObjectList unterschiedliche Objekte erkennen?
Zitat:
Delphi-Quellcode:
,
TCoupe(Auto)
sondern die weicheren Casts ala
Delphi-Quellcode:
, den so wäre dir das Problem sofort aufgefallen, weil es im Programm entsprechend geknallt hätte.
(Auto as TCoupe)
PS: Dein Pech war, daß der Zugriff auf das falsch gecastete Objekt nicht auch schon geknallt hatte, denn wenn FSitze erst in TCoupe deklariert wurde, dann gibt es dieses Feld in TAuto nicht, und somit greifst du auf etwas zu, was es nicht gibt, welches nicht unbedingt Gesund ist, für ein Programm. |
AW: TObjectList unterschiedliche Objekte erkennen?
Die bessere Lösung für das Problem wäre wohl die Nutzung der Polymorphie:
- packe eine (abstrakte) virtuelle Methode in TAuto - überschreibe die in den Subklassen - und rufe die einfach mit nem cast auf TAuto (nicht auf die Subklassen) auf ==> keine Casts auf Subklassen nötig und vor allem keine explizite Typabfrage mit is... Siehe auch: ![]() Und mal unabhängig vom konkreten Symptom sind das schon falsche Klassen. Neue Klassen sollte man nur erstellen, wenn diese neuen Klassen auch etwas neues können. Aber kann ein TCoupe mehr als ein TAuto? Oder ist das eigentlich nicht doch eher ein Attribut? mfg Christian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz