![]() |
Delphi-Version: 5
Prüfen und Casten auf einen Rutsch
Bin gerade aus Zufall auf folgende Idee gekommen, dass man die Prüfung mit is und eine anschliesende Cast-Operation zusammenfassen könnte:
Delphi-Quellcode:
Falls das jemand gut findet, darf er die Funktion behalten.
function IsKindOf(obj:TObject; AClass:TClass; var x):Boolean;
begin Result := obj is AClass; if Result then TObject(x) := obj else TObject(x) := nil; end; // Mit Hilfsfunktion procedure TForm1.Button1Click(Sender: TObject); var b : TButton; begin if IsKindOf(Sender, TButton, b) then b.Caption := 'ich bin ein Button'; end; // Ohne Hilfsfunktion procedure TForm1.Button1Click(Sender: TObject); var b : TButton; begin if Sender is TButton then begin b := TButton(Sender); b.Caption := 'ich bin ein Button'; end; end; |
AW: Prüfen und Casten auf einen Rutsch
Ist Delphi 5 wirklich zwingend, oder hast du das nur als minimal Version angegeben?
Denn ansonsten würde ich das über einen Class Helper erledigen:
Delphi-Quellcode:
Ich hoffe, der Code ist korrekt... Ist gerade einfach mal schnell aus dem Kopf runter geschrieben...
TObjectHelper = class helper(TObject)
public function TryCast<TCastType>(out Object: TCastType): Boolean; end; function TObjectHelper.TryCast<TCastType>(out Object: TCastType): Boolean; begin Result := Self is AClass; if Result then Object := Self else Object := nil; end; |
AW: Prüfen und Casten auf einen Rutsch
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var Button: TButton absolute Sender; begin if Sender is TButton then Button.Caption := 'ich bin ein Button'; end; Bei solchen Funktionen kenn ich es oft, daß sie den Ausgabewert nur setzen, wenn die Prüfung erfolgreich war.
Delphi-Quellcode:
Aber ich glaub es könnte fehlerunanfälliger sein, wenn man den Wert dennoch initialisiert (nil).
function TObjectHelper.TryCast<TCastType>(out Object: TCastType): Boolean;
begin Result := Self is AClass; if Result then Object := Self; end; |
AW: Prüfen und Casten auf einen Rutsch
Nachdem es eh ein out-Parameter ist und man nach einem False-Rückgabewert eh tunlichst nicht darauf zugreifen sollte, ists eigentlich egal. Die Frage ist nur, was ist gute Praxis?! ;)
|
AW: Prüfen und Casten auf einen Rutsch
Kleine Korrektur:
Delphi-Quellcode:
Allerdings könnte ein public sichtbarer
function TObjectHelper.TryCast<TCastType: Class>(out Instance: TCastType): Boolean;
begin Result := Self is TCastType; if Result then Instance:= Self else Instance:= nil; end;
Delphi-Quellcode:
das ganze übrige Helper Szenario obsolet machen.
helper for TObject
Besser wäre vielleicht ein Record:
Delphi-Quellcode:
type
TCaster = record function TryCast<TCastType: Class>(Source: TObject; out Target: TCastType): Boolean; end; function TCaster.TryCast<TCastType>(Source: TObject; out Target: TCastType): Boolean; begin Result := Source is TCastType; if Result then Target := Source else Target := nil; end; |
AW: Prüfen und Casten auf einen Rutsch
Nennt mich altmodisch, aber was ist gegen eine "einfache" Funktion, wie sx2008 es gezeigt hat, auszusetzen.
Was ist der Vorteil von Class-Helper. In den Beiträgen sehe ich zwar, wie der Classhelper definiert ist. Aber wie wird er angewendet? |
AW: Prüfen und Casten auf einen Rutsch
Ein ClassHelper erweitert eine Klasse um Methoden, die dann einfach benutzt werden können.
In diesem Beispiel also so
Delphi-Quellcode:
if Sender.TryCast<TEdit>( Edit ) then
Edit.Text := 'tut'; |
AW: Prüfen und Casten auf einen Rutsch
Zitat:
|
AW: Prüfen und Casten auf einen Rutsch
Zitat:
Delphi-Quellcode:
).
var x
|
AW: Prüfen und Casten auf einen Rutsch
Zitat:
Delphi-Quellcode:
wäre aber auch OK und käme ohne class helper aus. Leider kann Delphi (noch) keine globalen generischen Routinen. (Warum eigentlich?)
if TryCast<TEdit>(Sender, Edit) then
Edit.Text := 'tut'; |
AW: Prüfen und Casten auf einen Rutsch
Zitat:
Einfach eine implizite Klasse drum, um die Funktion, und schon ginge es ohne große Änderung des Compilers. Nja, aber wenn du OOP mit arbeitest, und diese "Funktion innerhalb von Methoden verwendest, dann kannst du immernoch den ClassHelper verwenden. Und im Notfall kombiniert man einfach Beides.
Delphi-Quellcode:
TCastHelper = class helper for TObject
class function TryCast<TCastType: Class>(Source: TObject; out Target: TCastType): Boolean; overload; function TryCast<TCastType: Class>(out Target: TCastType): Boolean; overload; end;
Delphi-Quellcode:
// z.B. im ButtonClick:
if x.TryCast(y) or TryCast(x, y) then |
AW: Prüfen und Casten auf einen Rutsch
Zitat:
|
AW: Prüfen und Casten auf einen Rutsch
Ja, ich hab mir z.B. ein generisches IfThen gebastelt (z.B. für Enums und Klassen) und weißt du wie blöd das
Delphi-Quellcode:
aussieht?
TGenerics.IfThen<TIrgendwas>(...)
Ich hätte es da lieber als überladene Prozedur zu den anderen existierenden IfThen's gehabt. :cry: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz