Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   is Operator akzeptiert auch Oberklassen? (https://www.delphipraxis.net/154116-operator-akzeptiert-auch-oberklassen.html)

xZise 28. Aug 2010 12:59

Delphi-Version: 2005

is Operator akzeptiert auch Oberklassen?
 
Moin,
es gab bestimmt diese Frage schon, aber ich weiß gerade nicht, wie man danach am besten sucht.

Aber wenn ich folgendes habe:
Delphi-Quellcode:
type
  TMutter = class;
  TKind = class(TMutter);
Wie teste ich dann, ob ein Objekt TMutter ist (und nicht TKind)?
Delphi-Quellcode:
var
  x : TObject;
begin
  x := TMutter.Create;
  x is TMutter // sollte true sein
  x is TKind // sollte false sein ist aber true
MfG
Fabian

daywalker9 28. Aug 2010 13:14

AW: is Operator akzeptiert auch Oberklassen?
 
Zitat:

Zitat von xZise (Beitrag 1045704)
Delphi-Quellcode:
type
  TMutter = class;
  TKind = class(TMutter);

var
  x : TObject;
begin
  x := TMutter.Create;
  x is TMutter // sollte true sein
  x is TKind // sollte false sein ist aber true

Also bei mir kommt sauber false bei der 2 Prüfung raus. Habe D2010

Meflin 28. Aug 2010 13:27

AW: is Operator akzeptiert auch Oberklassen?
 
Zitat:

Zitat von xZise (Beitrag 1045704)
Wie teste ich dann, ob ein Objekt TMutter ist (und nicht TKind)?

Also uns wurde hier eingetrichtert, dass die Verwendung derartiger Operatoren sowieso Code Smells sind :stupid:

Zu bevorzugen wäre, für den Grund der Überprüfung ein Attrbut o.ä. einzuführen ala
Code:
TMutter = class
public
  function canAnswer: Boolean;
end;

TKind = class(TMutter)
...

TMutter.canAnswer: Boolean
begin
  Result := false;
end;

TKind.canAnswer: Boolean
begin
  Result := true;
end;

xZise 28. Aug 2010 13:35

AW: is Operator akzeptiert auch Oberklassen?
 
Moin,
hmmm aber eigentlich wollte ich jetzt nicht mehrere Tausend Zeilen überprüfen und ersetzen.

Aber komisch, dass es in der Demo funktioniert. Weil ich habe folgende Klassen:
Delphi-Quellcode:
TPersonZeile = class(TZeile);
TLehrerZeile = class(TPersonZeile);
TSchuelerZeile = class(TPersonZeile);
Anfangs konnte gesagt werden: Suche nach "TSchuelerZeile" oder suche nach "TLehrerZeile". Jetzt gibt es aber auch Elemente die TPersonZeile direkt sind, aber dort findet er alles. Wenn ich jetzt da die Elemente rausnehme, dann sind auch TLehrerZeile dabei, obwohl nur TSchuelerZeile und TPersonZeile drin sein dürften.

Ich lasse das auf einen VST anzeigen. Und habe da im GetText:
Delphi-Quellcode:
if Zeile is TSchuelerZeile then
  foo
else if Zeile is TPersonZeile then
  Text := Zeile.Classname
else
  Text := 'Shit... ein Lehrer darf da gar net sein';
Und komischerweise tauchen im VST Werte wie TLehrerZeile auf.

implementation 28. Aug 2010 14:33

AW: is Operator akzeptiert auch Oberklassen?
 
Zitat:

Zitat von xZise (Beitrag 1045711)
Delphi-Quellcode:
if Zeile is TSchuelerZeile then
  foo
else if Zeile is TPersonZeile then
  Text := Zeile.Classname
else
  Text := 'Shit... ein Lehrer darf da gar net sein';
Und komischerweise tauchen im VST Werte wie TLehrerZeile auf.

Geh den Code doch mal Zeile für Zeile durch:
Delphi-Quellcode:
// Angenommen Zeile ist vom Typ TLehrerZeile
if Zeile is TSchuelerZeile then      // false, Zeile ist keine Schülerzeile
  foo
else if Zeile is TPersonZeile then   // true, Zeile ist PersonZeile
  Text := Zeile.Classname
else                                 // tritt nicht ein
  Text := 'Shit... ein Lehrer darf da gar net sein';
Das müsstest du schon umformulieren :wink:
Denn Lehrerzeilen fallen ja auch unter die Personenzeilen.
Wie wärs mit:
Delphi-Quellcode:
if Zeile is TSchuelerZeile then
  foo
else if Zeile is TLehrerZeile
  Text := 'Shit... ein Lehrer darf da gar net sein'
else
  Text := Zeile.Classname;

rollstuhlfahrer 28. Aug 2010 16:40

AW: is Operator akzeptiert auch Oberklassen?
 
Zitat:

Zitat von xZise (Beitrag 1045711)
Weil ich habe folgende Klassen:
Delphi-Quellcode:
TPersonZeile = class(TZeile);
TLehrerZeile = class(TPersonZeile);
TSchuelerZeile = class(TPersonZeile);

Das Problem ist, dass hier schon die Struktur falsch ist. Wenn du auf TPersonZeile prüfen willst, dann wirst du automatisch alle anderen auch bekommen, da diese ja alle von TPersonZeile abgeleitet wurden und dementsprechend alle Methoden und Funktionen haben, die TPersonZeile ja auch hat. Du müsstest dafür einen eigenen Typ nehmen oder TLehrerZeile und TSchuelerZeile auch von TZeile ableiten.

Bernhard

PS: Dass der is-Operator auch Vorfahren-Klassen akzeptiert ist sogar gewünscht. Sonst hätte die VCL allerhand Probleme, weil sie sonst nicht dynamisch mit selbst erstellten Klassen zurecht käme und du unter anderem auch ein einfaches Drag&Drop vergessen kannst. (Dort wird die Prüfung ja immer verwendet)

PS2: Wie will denn die VCL Bilder anzeigen, wenn sie nicht auf
Delphi-Quellcode:
is TGraphic
prüfen kann?

xZise 28. Aug 2010 16:41

AW: is Operator akzeptiert auch Oberklassen?
 
Naja, aber wenn "x is TKind" false liefert, warum liefert es dann bei mir true? Und was ist, wenn eine 3. Klasse von TPersonZeile abgeleitet wird.

MfG
Fabian

PS: [redbox]@Bernhard: Deshalb suche ich eine Möglichkeit zu testen, ob x nur TPersonZeile ist und keine Abgeleitete. Und naja ansonsten steht das hier im Post in der 1. Frage oder nich ;)[/redbox]

idefix2 28. Aug 2010 16:47

AW: is Operator akzeptiert auch Oberklassen?
 
Du könntest Zeile.Classname verwenden. damit bekommst Du genau die richtige Klasse.

rollstuhlfahrer 28. Aug 2010 16:52

AW: is Operator akzeptiert auch Oberklassen?
 
Macht es nicht viel mehr Sinn, dafür einfach eine neue Klasse zu definieren und nach der zu suchen? Alles andere mit String-Vergleich und Varianten-Funktionen finde ich etwas übertrieben und was das schlimmste ist: Es ist wartungsbedürftig. Der Delphi-eigene IS-Operator wird auch in ferner Zukunft wie heute funktionieren. Außerdem gibt es Syntax-Fehler, wenn mal was nicht stimmt. Nutzt du z.B. die Methode .ClassString und vergleichst diese mit einer Konstanten, kann es zu Problemen kommen, wenn du dein Programm wegen einem anderen Problem ändern musst.
Du kannst es aber mal mit .ClassType (Da gibt es eine Funktion, die ein TClass zurückliefert) versuchen und dann mit deiner Klasse vergleichen. Hier sollten keine Vorfahren dabei sein.

Bernhard

PS: Beispiel zu .ClassType in #11

xZise 28. Aug 2010 16:53

AW: is Operator akzeptiert auch Oberklassen?
 
Zitat:

Zitat von idefix2 (Beitrag 1045766)
Du könntest Zeile.Classname verwenden. damit bekommst Du genau die richtige Klasse.

Stimmt, aber ich glaube da nehme ich eher sowas wie .Class .ClassType, weil dann meckert der Compiler falls sich der Name ändert und das Refactoring erfasst das mit.

Argh und mir fällt gerade ein, dass ich ja oben mist angegeben habe. Und zwar ist mein Mutter-Kind Beispiel genau das Gegenteil! Und zwar müsste es ja
Delphi-Quellcode:
x := TKind.Create;
heißen (aber das scheint euch ja auch nicht aufgefallen zu sein :mrgreen: ).

MfG
Fabian

PS: Okay scheint wohl eher .ClassType zu sein :P


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:34 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz