AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Funktion, die beliebigen Typ zuweist und als Bool auswertet
Thema durchsuchen
Ansicht
Themen-Optionen

Funktion, die beliebigen Typ zuweist und als Bool auswertet

Ein Thema von WladiD · begonnen am 2. Mär 2011 · letzter Beitrag vom 2. Mär 2011
Antwort Antwort
Seite 1 von 2  1 2      
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#1

Funktion, die beliebigen Typ zuweist und als Bool auswertet

  Alt 2. Mär 2011, 10:21
Delphi-Version: XE
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.
Waldemar Derr
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

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

  Alt 2. Mär 2011, 10:26
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 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.
$2B or not $2B

Geändert von himitsu ( 2. Mär 2011 um 10:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#3

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

  Alt 2. Mär 2011, 10:27
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;
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.

Geändert von Deep-Sea ( 2. Mär 2011 um 10:37 Uhr)
  Mit Zitat antworten Zitat
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#4

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

  Alt 2. Mär 2011, 10:41
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

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?
Waldemar Derr
  Mit Zitat antworten Zitat
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#5

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

  Alt 2. Mär 2011, 10:49
PS: Sowas 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.
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.
Waldemar Derr
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

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

  Alt 2. Mär 2011, 10:52
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.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#7

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

  Alt 2. Mär 2011, 11:00
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.
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".
Waldemar Derr
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#8

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

  Alt 2. Mär 2011, 11:17
[...] denn weitere Bedingungen werden ggf. gar nicht erst ausgewertet, im Gegensatz zur "lesbareren Version".
Wie meinst du das?
Bei der Abfrage If A and B then ... ; wird B auch nicht mehr geprüft, wenn A bereits false ist.
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#9

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

  Alt 2. Mär 2011, 11:21
[...] denn weitere Bedingungen werden ggf. gar nicht erst ausgewertet, im Gegensatz zur "lesbareren Version".
Wie meinst du das?
Bei der Abfrage 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).
Waldemar Derr
  Mit Zitat antworten Zitat
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#10

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

  Alt 2. Mär 2011, 14:01
Der Vollständigkeit halber hänge ich die Unit an, vielleicht kann es jemand gebrauchen.
Angehängte Dateien
Dateityp: pas SetCheck.pas (2,3 KB, 1x aufgerufen)
Waldemar Derr
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:45 Uhr.
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