Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - prüfen was für eine klasse hinter einem pointer steckt
cbs - Mi 24.09.03 20:07
Titel: prüfen was für eine klasse hinter einem pointer steckt
huhu
ich möchte ein object mit einem TreeNode (von TTreeView) verknüpfen und beim auswählen dieses Nodes einige Daten des Objects verarbeiten/anzeigen.
ich habe dazu in der
Data eigenschaft des Nodes mein Object abgelegt (bessergesagt den pointer darauf)
wenn der User auf einen Node klickt möchte ich die Data eigenschaft des selektierten Nodes auslesen und abhängig davon was es für ein Object ist daten anzeigen oder verarbeiten. soll heißen das es verschiedene objecte sein können und ich möchte herrausfinden was es für ein object ist damit ich entsprechend an die daten wieder herran komme
also: wie kann ich prüfen was für eine klasse hinter einem pointer steckt?
ungefähr so stell ich mir das vor (funktioniert natürlich nicht)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| if Node.Data = TData then begin TData(Node.Data). end;
if Node.Data = TDataProject then begin TDataProject(Node.Data). end; |
ich hab da schon abenteuerliche kombinationen mit is und as probiert. aber habs noch nicht hinbekommen
UC-Chewie - Mi 24.09.03 20:10
Du musst dein = aus dem Vergleich eigentlich nur durch is ersetzen.
Alternativ kannst du einen Cast nach TObject machen und dort die Methode ClassName aufrufen. Da bekommst du den Namen des Typs als String.
cbs - Mi 24.09.03 20:22
jo danke dir UC-Chewie
das mit dem is funtioniert nicht
Delphi-Quelltext
1: 2: 3:
| if Node.Data is TData then begin
end; |
Compiler hat folgendes geschrieben: |
Operator ist auf diesen Operandentyp nicht anwendbar |
aber die sache mit classname hilft mir schon weiter
Delphi-Quelltext
1:
| TObject(Node.Data).ClassName |
schicke sache, aber kann ich das auch direkt prüfen? ohne den umweg mit classname?
Shark - Mi 24.09.03 21:15
wenn Du alles von einer bestimmten Klasse abgeleitet hast, dann funktioniert
"is" wie folgt
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| var Object: TUrClass <- Beispiel
Object := Node.Data; if Object is TClass then ... |
einen unbestimmten Pointer kannst Du mit
is nicht vergleichen!
Moderiert von
Klabautermann: Delphi-Tags hinzugefügt.
UC-Chewie - Mi 24.09.03 21:22
Ach so, Data ist ein Pointer.
Dann so:
Delphi-Quelltext
1:
| if TObject(Node.Data) is TData then |
Zitat: |
schicke sache, aber kann ich das auch direkt prüfen? ohne den umweg mit classname? |
Wieso Umweg?
Shark - Mi 24.09.03 21:28
Man sollte
"as" noch ansprechen:
Delphi-Quelltext
1: 2: 3: 4: 5:
| Object1 : TUrClass; Object2 : TClass;
if Object1 is TClass then Object2 := Object1 as TClass; |
Moderiert von
Klabautermann: Delphi-Tags hinzugefügt.
cbs - Mi 24.09.03 23:00
ah danke euch beiden :D
Shark hat folgendes geschrieben: |
wenn Du alles von einer bestimmten Klasse abgeleitet hast... |
Sämtliche klassen haben doch eh TObject als Urklasse oder? also kann ich doch generell mit TObject die Klasse prüfen oder?
also
Delphi-Quelltext
1:
| TObject(Node.Data) is TData |
UC-Chewie hat folgendes geschrieben: |
Wieso Umweg? |
jo hast recht. die lösung mitclassname ist auch nicht viel schwieriger/komplizierter als direkt mit is zu prüfen
thx nochmal :lol:
datensender - Do 25.09.03 09:12
shark hat folgendes geschrieben: |
Man sollte "as" noch ansprechen:
Object1 : TUrClass;
Object2 : TClass;
if Object1 is TClass then
Object2 := Object1 as TClass; |
wenn du vorher bereits mit "is" prüfst, wäre ein anschließendes "as" doppelt gemoppelt... ("as" prüft dann nämlich noch einmal auf die Klasse, wobei das Ergebnis dann in diesem Fall
immer gültig ist und nie eine Fehlermeldung erzeugt wird/werden kann... andernfalls wäre bereits "is" abgesprungen...)
nach dem Test mit "is" kannst du also auch gleich statisch casten....
cbs - Do 25.09.03 09:27
datensender hat folgendes geschrieben: |
nach dem Test mit "is" kannst du also auch gleich statisch casten.... |
örm...
wenn du das damit meinst
Delphi-Quelltext
1: 2: 3:
| if TObject(Node.Data) is TData then begin TData(Node.Data). end; |
dann mach ich das jetzt so :lol:
und was wäre ein dynamisches "casten" :?:
datensender - Do 25.09.03 12:26
"as" ist in Delphi u.A. für dynamische Typumwandlung gedacht und
das funktioniert dann auch nur im Zusammenhang mit Objekten,
weil bestimmte Typinformationen für eine solche Umwandlung
notwendig werden (*1)...
Es findet zur Laufzeit eine Überprüfung auf eine sichere Umwandlung statt,
bei der (1:) die Klassenhierarchie des betroffenen Objektes durchsucht wird...
(_AsClass (oder auch _IsClass für "is") in der System.pas für Details)
Ist die Umwandlung mit "as" nicht möglich, wird eine
Exception ausgelöst...
D.h. also auch, dass für dyn. Casts extra Code erzeugt wird... (beim statischen Casten hingegen nicht.
Da wird dem Compiler nur klar gemacht, wie er was zu behandeln hat, soweit möglich...
dass eine Umwandlung möglich ist bedeutet aber nicht, dass
sie auch immer richtig ist... )
cbs - Do 25.09.03 13:28
also um das mal ein bischen zu verinnerlichen hab ich mal folgenden test gemacht
Button1Click ist einem Button als OnClick ereigniss zugewiesen
Delphi-Quelltext
1: 2: 3: 4:
| procedure TFormMain.Button1Click(Sender: TObject); begin ShowMessage(TButton(Sender).Caption); end; |
die beschriftung wird korrekt angezeigt
jetzt das selbe mit
as
Delphi-Quelltext
1: 2: 3: 4:
| procedure TFormMain.Button1Click(Sender: TObject); begin ShowMessage((Sender as TButton).Caption); end; |
auch hier wird die beschriftung korrekt angezeigt
dann hab ich mal spassens halber ein Edit-Feld auf mein Formular platziert und im OnClick ereigniss die selbe prozedure zugewiesen
Delphi-Quelltext
1: 2: 3: 4:
| procedure TFormMain.Button1Click(Sender: TObject); begin ShowMessage(TButton(Sender).Caption); end; |
zeigt mir den korrekten aktuellen
Text vom Edit-Feld an :!:
wie geht das :?: TEdit hat keine eigenschaft namens caption
bei
Delphi-Quelltext
1: 2: 3: 4:
| procedure TFormMain.Button1Click(Sender: TObject); begin ShowMessage((Sender as TButton).Caption); end; |
wird wie du sagst eine exception ausgelöst
maximus - Do 25.09.03 13:56
@Caption: das liegt daran, dass die propertie 'caption' und 'text' beide die selben functionen benutzen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| TControl = class(TComponent) property Caption: TCaption read GetText write SetText stored IsCaptionStored; ... property Text: TCaption read GetText write SetText; ... end; |
und da bei dem typeCast nur auf ein feld, eines gemeinsamen vorfahren, zugegriffen wird, ist alles in bester ordnung mit dem illegalen typeCast!
hab mal gehört, dass is und as auslaufmodelle sind und nicht mehr benutzt werden sollten. Ich benutz sowieso immer TclassX.inheritedFrom(TBla...) und dann statische casts :wink:
cbs - Do 25.09.03 14:23
maximus hat folgendes geschrieben: |
liegt daran, dass die propertie 'caption' und 'text' beide die selben functionen benutzen |
alles klar :wink:
maximus hat folgendes geschrieben: |
hab mal gehört, dass is und as auslaufmodelle sind und nicht mehr benutzt werden sollten. Ich benutz sowieso immer TclassX.inheritedFrom(TBla...) |
die OH sagt dazu aber folgendes
OnlineHilfe hat folgendes geschrieben: |
InheritsFrom entspricht dem Delphi-Operator is |
also doch nicht so ganz ein "auslaufmodell" :wink:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!