Autor |
Beitrag |
cbs
      
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: Mi 24.09.03 20:07
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
      
Beiträge: 531
WinXP
D5 Ent
|
Verfasst: 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.
_________________ Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
|
|
cbs 
      
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 87
98, XP
D3, D5, D7
|
Verfasst: 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
      
Beiträge: 531
WinXP
D5 Ent
|
Verfasst: 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?
_________________ Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
|
|
Shark
      
Beiträge: 87
98, XP
D3, D5, D7
|
Verfasst: 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 
      
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: Mi 24.09.03 23:00
ah danke euch beiden
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 
|
|
datensender
      
Beiträge: 18
Windows 2000 P / Gentoo
D5 Enterprise
|
Verfasst: 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....
_________________ "...haben uns verirrt, kommen aber gut voran" (Tom DeMarco)
Zuletzt bearbeitet von datensender am Do 25.09.03 14:08, insgesamt 3-mal bearbeitet
|
|
cbs 
      
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: 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
und was wäre ein dynamisches "casten" 
|
|
datensender
      
Beiträge: 18
Windows 2000 P / Gentoo
D5 Enterprise
|
Verfasst: 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... )
_________________ "...haben uns verirrt, kommen aber gut voran" (Tom DeMarco)
Zuletzt bearbeitet von datensender am Do 25.09.03 14:11, insgesamt 2-mal bearbeitet
|
|
cbs 
      
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: 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 
_________________ mfg.
mâximôv
|
|
cbs 
      
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: 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
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" 
|
|