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/)
-   -   Delphi Prüfen und Casten auf einen Rutsch (https://www.delphipraxis.net/169425-pruefen-und-casten-auf-einen-rutsch.html)

sx2008 18. Jul 2012 21:05

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:
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;
Falls das jemand gut findet, darf er die Funktion behalten.

s.h.a.r.k 18. Jul 2012 21:24

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:
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;
Ich hoffe, der Code ist korrekt... Ist gerade einfach mal schnell aus dem Kopf runter geschrieben...

himitsu 18. Jul 2012 21:54

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:
function TObjectHelper.TryCast<TCastType>(out Object: TCastType): Boolean;
begin
  Result := Self is AClass;
  if Result then
    Object := Self;
end;
Aber ich glaub es könnte fehlerunanfälliger sein, wenn man den Wert dennoch initialisiert (nil).

s.h.a.r.k 18. Jul 2012 22:03

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?! ;)

Uwe Raabe 18. Jul 2012 23:04

AW: Prüfen und Casten auf einen Rutsch
 
Kleine Korrektur:

Delphi-Quellcode:
function TObjectHelper.TryCast<TCastType: Class>(out Instance: TCastType): Boolean;
begin
  Result := Self is TCastType;
  if Result then
    Instance:= Self
  else
    Instance:= nil;
end;
Allerdings könnte ein public sichtbarer
Delphi-Quellcode:
helper for TObject
das ganze übrige Helper Szenario obsolet machen.

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;

bernau 19. Jul 2012 00:55

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?

Sir Rufo 19. Jul 2012 01:03

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';

bernau 19. Jul 2012 01:34

AW: Prüfen und Casten auf einen Rutsch
 
Zitat:

Zitat von Sir Rufo (Beitrag 1175147)
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';

Danke. Wieder was gelernt.

uligerhardt 19. Jul 2012 07:14

AW: Prüfen und Casten auf einen Rutsch
 
Zitat:

Zitat von bernau (Beitrag 1175146)
Nennt mich altmodisch, aber was ist gegen eine "einfache" Funktion, wie sx2008 es gezeigt hat, auszusetzen.

Das einzige, was mich stört, ist die fehlende Typsicherheit (siehe Parameter
Delphi-Quellcode:
var x
).

uligerhardt 19. Jul 2012 07:19

AW: Prüfen und Casten auf einen Rutsch
 
Zitat:

Zitat von Sir Rufo (Beitrag 1175147)
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';

Delphi-Quellcode:
if TryCast<TEdit>(Sender, Edit) then
  Edit.Text := 'tut';
wäre aber auch OK und käme ohne class helper aus. Leider kann Delphi (noch) keine globalen generischen Routinen. (Warum eigentlich?)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:58 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