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 Funktion, die beliebigen Typ zuweist und als Bool auswertet (https://www.delphipraxis.net/158767-funktion-die-beliebigen-typ-zuweist-und-als-bool-auswertet.html)

WladiD 2. Mär 2011 09:21

Delphi-Version: XE

Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Hallo @all,

ich liebe Delphi, doch es nervt mich schon seit Ewigkeiten, dass es keine Möglichkeit gibt eine Variable zu setzen und gleichzeitig zu einem Bool auszuwerten. Um besser zu verstehen, was ich meine hier ein Code-Fetzen, der z.B. in PHP/JavaScript funktioniert:

Code:
function Foo($Value)
{
  if ($LocalValue = $Value * 10) && ($LocalValue > 100)
    return $LocalValue - 1;
  else
    return $LocalValue + 1;
}
Man beachte, dass $LocalValue in jedem Fall gesetzt wird, aber die nächste Bedingung nur ausgewertet wird, wenn es zu Boolean(True) gewandelt werden kann, was bei numerischen Typen alles <> 0 ist.

Das ist nur ein stupides Beispiel, aber wenn ich es zu Delphi übersetze:

Delphi-Quellcode:
function Foo(Value:Integer):Integer;
begin
  Result:=Value * 10; // Das ist das was mich nervt: zusätzliche Zeile
  if Result > 100 then
    Result:=Result - 1
  else
    Result:=Result + 1;
end;
Naja dachte ich mir, dann ist es doch kein Problem eine überladene Funktion zuschreiben, wie z.B.:

Delphi-Quellcode:
function SetCheck(var Target:Integer; const Value:Integer):Boolean; overload; inline;
function SetCheck(var Target:Int64; const Value:Int64):Boolean; overload; inline;
function SetCheck(var Target:String; const Value:String):Boolean; overload; inline;

...

function SetCheck(var Target:Integer; const Value:Integer):Boolean;
begin
   Target:=Value;
   Result:=Value <> 0;
end;

...
Hat auch wunderbar funktioniert (für einfache Typen), bis ich zum TObject bzw. IInterface kam:

Delphi-Quellcode:
function SetCheck(var Target:TObject; const Value:TObject):Boolean;
begin
   Target:=Value;
   Result:=Assigned(Value);
end;
Sieht logisch aus, aber leider lässt es sich nur mit TObject und sonst mit keinem anderen Nachkommen verwenden, da Delphi ja die Einschränkung hat, dass var-Parameter dem deklarierten Typ exakt entsprechen müssen.

Habt ihr hierfür eine Lösung? Vielleicht über Assembler?

Die Anforderung ist ja ganz simpel: Die Funktion soll in jedem Fall einen Wert an eine Variable zuweisen und diesen als Boolean auswerten.

himitsu 2. Mär 2011 09:26

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Ein untypisierter VAR-Parameter?

Aber da mußt du dann selber außassen, daß die Typen passen.

Delphi-Quellcode:
function SetCheck(var Target; const Value: TObject): Boolean;
begin
  TObject(Target) := Value; // evtl. PObject(@Target)^ := Value;
  Result := Assigned(Value);
end;
Wenn du es als Klassenmetode machst, dann auch so:
(als eigenständige Funktion ging das mit den Gernerics, glaub ich, leider nicht)
Delphi-Quellcode:
function {TMyClass.}SetCheck<T: object>(var Target: T; Value: T): Boolean;
begin
  Target := Value;
  Result := Assigned(Value);
end;

if SetCheck<TDeineKlasse>(X, Y) then
PS: Sowas
Delphi-Quellcode:
if ($LocalValue = $Value * 10)
wird z.B. von Netbeens in PHP gern mal "bemängelt", da es nicht wirklich der Lesbarkeit des Codes dienlich ist. :stupid:

Deep-Sea 2. Mär 2011 09:27

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Wie wäre es mit einer generischen Funktion?! Dann musst du halt die Klasse immer mit angeben ...

Nachtrag:
Also z.B. so in der Art.
Delphi-Quellcode:
TForm1 = class(TForm)
public
  procedure Test<T>(var AItem: T);
end;

procedure TForm1.Test<T>(var AItem: T);
begin
  // Mach was mit AItem
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LObject: TButton;
begin
  Test<TButton>(LObject);
end;

WladiD 2. Mär 2011 09:41

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Zitat:

Zitat von Deep-Sea (Beitrag 1085301)
Wie wäre es mit einer generischen Funktion?! Dann musst du halt die Klasse immer mit angeben ...

Wieso bin ich da eigentlich nicht gleich draufgekommen :roll:

Hab mal auf die schnelle das hier geschrieben:

Delphi-Quellcode:
unit SetCheck;

interface

type
   TSetCheck = record
      class function O<T:class>(var Target:T; const Value:T):Boolean; static; inline; // O = Object
      class function I<T:IInterface>(var Target:T; const Value:T):Boolean; static; inline; // I = Interface
   end;

implementation

class function TSetCheck.I<T>(var Target:T; const Value:T):Boolean;
begin
   Target:=Value;
   Result:=Assigned(Target);
end;

class function TSetCheck.O<T>(var Target:T; const Value:T):Boolean;
begin
   Target:=Value;
   Result:=Assigned(Target);
end;

end.
Und schwups funktioniert soetwas hier:

Delphi-Quellcode:
function TMainForm.CreateFormConfig(XMLConfig:TXMLConfig):IXMLDOMNode;
begin
   if not TSetCheck.I<IXMLDOMNode>(Result, inherited CreateFormConfig(XMLConfig)) then
      Exit;
...
end;
SUPER. Danke für den Schups!

Jetzt stellt sich nur die Frage: Ist der Compiler smart enough, um generische Funktionen inline einzubinden?

Anders macht es ja kein Sinn, denn ich will zwar den Komfort des Ganzen, aber keine unnötigen Sprünge.

Was meint ihr?

WladiD 2. Mär 2011 09:49

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Zitat:

Zitat von himitsu (Beitrag 1085300)
PS: Sowas
Delphi-Quellcode:
if ($LocalValue = $Value * 10)
wird z.B. von Netbeens in PHP gern mal "bemängelt", da es nicht wirklich der Lesbarkeit des Codes dienlich ist. :stupid:

Ja das stimmt, der Operator "=" wird allzu oft (besonders durch Anfänger) übersehen bzw. als "==" durch den Code-Leser interpretiert. Aber ich denke eine knackige Funktion hebelt diesen Nachteil aus.

P.S.: Einen untypisierten var-Parameter wollte ich vermeiden.

Neutral General 2. Mär 2011 09:52

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Hallo,

Okay, also aus dem hier:

Delphi-Quellcode:
function Foo(Value:Integer):Integer;
begin
  Result:=Value * 10; // Das ist das was mich nervt: zusätzliche Zeile
  if Result > 100 then
    Result:=Result - 1
  else
    Result:=Result + 1;
end;
Wird jetzt das hier:

Delphi-Quellcode:
function Foo(Value:Integer):Integer;
begin
  if (TSetCheck.I<Integer>(Result, Value*10)) and (Result > 100) then
    Result:=Result - 1
  else
    Result:=Result + 1;
end;
Findest du das wirklich schöner/übersichtlicher als das oben?
Den Code oben versteht man 1000x besser als DAS da. Und schneller wirds mit Sicherheit auch sein. :roll:

WladiD 2. Mär 2011 10:00

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Zitat:

Zitat von Neutral General (Beitrag 1085304)
Hallo,

Delphi-Quellcode:
function Foo(Value:Integer):Integer;
begin
  if (TSetCheck.I<Integer>(Result, Value*10)) and (Result > 100) then
    Result:=Result - 1
  else
    Result:=Result + 1;
end;
Findest du das wirklich schöner/übersichtlicher als das oben?
Den Code oben versteht man 1000x besser als DAS da. Und schneller wirds mit Sicherheit auch sein. :roll:

Nein daraus wird (die Unit wird erweitert):

Delphi-Quellcode:
function Foo(Value:Integer):Integer;
begin
  if (TSetCheck.Common(Result, Value*10)) and (Result > 100) then
    Result:=Result - 1
  else
    Result:=Result + 1;
end;
Das war ja nur ein sinnloses Beispiel. Wegen der Geschwindigkeit bin ich mir nicht sicher, wenn der Compiler der inline Direktive folgt, dann dürfte es sogar schneller werden, denn weitere Bedingungen werden ggf. gar nicht erst ausgewertet, im Gegensatz zur "lesbareren Version".

Deep-Sea 2. Mär 2011 10:17

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Zitat:

Zitat von WladiD (Beitrag 1085305)
[...] denn weitere Bedingungen werden ggf. gar nicht erst ausgewertet, im Gegensatz zur "lesbareren Version".

Wie meinst du das?
Bei der Abfrage
Delphi-Quellcode:
If A and B then ... ;
wird B auch nicht mehr geprüft, wenn A bereits false ist.

WladiD 2. Mär 2011 10:21

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Zitat:

Zitat von Deep-Sea (Beitrag 1085310)
Zitat:

Zitat von WladiD (Beitrag 1085305)
[...] denn weitere Bedingungen werden ggf. gar nicht erst ausgewertet, im Gegensatz zur "lesbareren Version".

Wie meinst du das?
Bei der Abfrage
Delphi-Quellcode:
If A and B then ... ;
wird B auch nicht mehr geprüft, wenn A bereits false ist.

Genau so ist es: Boolesche Kurzauswertung. Siehe Delphi-Compiler-Direktive {$BOOLEVAL OFF}/{$B-} (Vorgabe).

WladiD 2. Mär 2011 13:01

AW: Funktion, die beliebigen Typ zuweist und als Bool auswertet
 
Liste der Anhänge anzeigen (Anzahl: 1)
Der Vollständigkeit halber hänge ich die Unit an, vielleicht kann es jemand gebrauchen.


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