Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Problem mit is operator
Geri - So 30.11.08 13:00
Titel: Problem mit is operator
Hallo zusammen
Ich habe eine Klassendefinition mit :
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| Type TBaseClass = class Constructor Create(); End;
TTestClassA(TBaseClass) Constructor Create(); End;
TTestClassB(TTestClassA) Constructor Create(); End;
Procedure TestClass(L:TList); var El:TBaseClass; TC:TTestClass; Begin El:=L[0]; if (El is TTestClassA) then Begin .. End else if (El is TTestClassB) then Begin ... End
End; |
Gerne möchte ich in der Prozedur TestClass mit Hilfe des is-Operators herausfinden um welche Klasse es sich handelt. Bei einm anderen Programm (auf einem anderen PC) ist mir das gelungen.
Wenn ich das Programm im Debugger durchsteppe und an der Stelle
if (El ist TTestClassA) mir im Debugger den Klassennamen anschauen will, dann steht für den Watch-Ausdruck
El.Classnae : Nicht verfügbarer Wert und die Klasse TTestClassB wird nie erkannt.
Wenn ich den Klassenanme zuerst als String auslese und dann Prüfe, dann funktioniert es:
s:String;
s:=El.Classname;
if s = 'TTestClassB' then
Begin
...
end;
Erkennt ihr vielleicht das Problem hier? Liegt es etwa an betimmten IDE-Einstellungen?
Vielen Dank für Eure Hilfe
Geri
PS: Ich verwende Delphi 2005, personal
jakobwenzel - So 30.11.08 13:09
Jede TestClassB ist auch eine TestClassA.
Deshalb wird bei den TestClassBs auch der Code für TestClassA ausgeführt, und der else-Zweig wird gar nicht mehr aufgerufen.
Geri - So 30.11.08 13:19
Hallo Jakob
Vielen Dank für Deinen Hinweis. Das ist sehr interessant.
Ich habe aber ein Programm mit ähnlicher Klassendefinition, dort arbeite ich exzessiv mit dem is-Operator und dieses Problem existiert komischerweise nicht oder mir ist es bisher nicht als Bug aufgefallen
Ich habe das Problem nun mit
if El.Classtype = TTestClassA then ...
gelöst. Das funktioniert
Gibt es dazu noch eine bessere Lösung?
Beste Grüsse
Geri
jakobwenzel - So 30.11.08 13:31
Also mit folgendem Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| program Project1;
{$APPTYPE CONSOLE} Type TBaseClass = class End;
TTestClassA = class(TBaseClass) End;
TTestClassB=class(TTestClassA) End;
function TestClass(el:TBaseClass):String; Begin if (El is TTestClassA) then Begin result:='TTestClassA'; End else if (El is TTestClassB) then Begin result:='TTestClassB'; End else result:='Other';
End;
var c:TBaseClass; begin c:=TBaseClass.Create; writeln('TBaseClass: '+TestClass(c)); c.Free; c:=TTestClassA.Create; writeln('TTestClassA: '+TestClass(c)); c.Free; c:=TTestClassB.Create; writeln('TTestClassB: '+TestClass(c)); c.Free; ReadLn; end. |
Krieg ich 2 mal TTestClassA als Ausgabe.
Wenn du bei der If-Abfrage zuerst auf TTestClassB und dann auf TTestClassA prüfst, würde es perfekt gehen.
Geri - So 30.11.08 14:01
Hallo Jakob
Vielen Dank für Deine sehr ausführliche Darstellung des Problems und er Lösung! Das finde ich sehr nett!
Ja, du hast recht, wenn ich zuerst nach TTestClassB abfragen würde dann würde es klappen. Mir gefältt aber der Einsatz
Delphi-Quelltext
1: 2: 3: 4:
| if (El.ClassType = 'TTestClassB) then Begin .. End; |
besser, weil er keine Ordnung der Abfrage voraussetzt.
Offen bleibt für mich aber noch wieso man beimn Watch-Ausdruck El.ClassName im Debug-Fenster die Ausgabe "nicht verfügbarer Wert" erhält. Hat das vielleicht etwas mit der internen Codeoptimierung zu tun. Ich habe alle mir bekannten Debug-Schalter eingeschaltet und Codeoptimierung ausgeschaletet...:)
Beste Grüsse
Geri
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!