Autor Beitrag
cbs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: 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)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if Node.Data = TData then begin
  TData(Node.Data).{blabla}
end;

if Node.Data = TDataProject then begin
  TDataProject(Node.Data).{blabla}
end;


ich hab da schon abenteuerliche kombinationen mit is und as probiert. aber habs noch nicht hinbekommen
UC-Chewie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 531

WinXP
D5 Ent
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: Mi 24.09.03 20:22 
jo danke dir UC-Chewie

das mit dem is funtioniert nicht

ausblenden 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

ausblenden Delphi-Quelltext
1:
TObject(Node.Data).ClassName					


schicke sache, aber kann ich das auch direkt prüfen? ohne den umweg mit classname?
Shark
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 87

98, XP
D3, D5, D7
BeitragVerfasst: Mi 24.09.03 21:15 
wenn Du alles von einer bestimmten Klasse abgeleitet hast, dann funktioniert "is" wie folgt

ausblenden 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 user profile iconKlabautermann: Delphi-Tags hinzugefügt.
UC-Chewie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 531

WinXP
D5 Ent
BeitragVerfasst: Mi 24.09.03 21:22 
Ach so, Data ist ein Pointer.
Dann so:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 87

98, XP
D3, D5, D7
BeitragVerfasst: Mi 24.09.03 21:28 
Man sollte "as" noch ansprechen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Object1 : TUrClass;
Object2 : TClass;

if Object1 is TClass then
  Object2 := Object1 as TClass;


Moderiert von user profile iconKlabautermann: Delphi-Tags hinzugefügt.
cbs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: 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
ausblenden 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
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 18

Windows 2000 P / Gentoo
D5 Enterprise
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: 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

ausblenden 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
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 18

Windows 2000 P / Gentoo
D5 Enterprise
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: 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
ausblenden 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
ausblenden 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
ausblenden 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
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Do 25.09.03 13:56 
@Caption: das liegt daran, dass die propertie 'caption' und 'text' beide die selben functionen benutzen:

ausblenden 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:

_________________
mfg.
mâximôv
cbs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: 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: