Hallo Himitsu,
in den letzten Tagen habe ich nach Deiner Anregung Einiges zu
anonymen Methoden gelesen und ausprobiert. Von Deinem Beispiel unter
#7 nimmt mein Compiler (10.3 Rio) folgende Zeile
nicht an:
Zitat:
Z: reference to function(): Boolean; // alles, inkl. anonymer Methoden (nicht direkt als VAR ... muß einen TYPE haben)
und meldet; E2003 Undeklarierter Bezeichner: 'Reference'. Aber es funktioniert über eine „benannte“ Typendeklaration wie z. B.:
Delphi-Quellcode:
Type
TMyAnonymus = reference to function(): Boolean;
Var
z: TMyAnonymus;
Möglicherweise habe ich in meinen Compiler-Optionen etwas falsch eingestellt. Auch die Zeile
L: class of TTest;
kennt mein Compiler (noch) nicht. Aber Deine Anregungen habe ich verstanden und dankend aufgenommen.
Ich habe nun ein Beispiel aus
Rolliston: Delphi XE2 Foundations (2012), S. 192-193 konkret auf meinen Anwendungsfall etwas angepaßt:
Delphi-Quellcode:
program Anonymus_Test_2;
{$APPTYPE CONSOLE}
{$R *.res}
Uses
System.SysUtils;
Type
DoubleDouble =
Record
X:
Array [0 .. 1]
of Double;
End;
Type
TMyAnonMethod = Reference
To Function(
CONST Rec: DoubleDouble): DoubleDouble;
Procedure Print(Text:
String;
CONST Rec: DoubleDouble);
overload;
VAR
S:
String;
Begin
S := Text + Rec.X[0].ToString + '
+ ' + Rec.X[1].ToString;
WriteLn(S);
End;
{Print}
{---------}
Function Standalone(
CONST Rec: DoubleDouble): DoubleDouble;
Begin
Print('
DoubleDouble-Rec to the standalone function = ', Rec);
End;
{Standalone}
{--------------}
Type
TTest =
class
Function OrdinaryMethod(
CONST Rec: DoubleDouble): DoubleDouble;
End;
Function TTest.OrdinaryMethod(
CONST Rec: DoubleDouble): DoubleDouble;
Begin
Print('
DoubleDouble-Rec to the ordinary method = ', Rec);
End;
{TTest.OrdinaryMethod}
{------------------------}
Procedure TestAssignment;
Var
Ref1, Ref2, Ref3: TMyAnonMethod;
Obj: TTest;
X, Y, Z: DoubleDouble;
Begin
Ref1:= Standalone;
Obj := TTest.Create;
Try
Ref2:= Obj.OrdinaryMethod;
Ref3:=
Function(
CONST Rec: DoubleDouble): DoubleDouble
// OHNE Semikolon!!!!!!
Begin
Print('
DoubleDouble-Rec to the anonymous method = ', Rec);
End;
// Aufruf der Funktionen:
X.X[0] := 1;
X.X[1] := 11;
Y.X[0] := 2;
Y.X[1] := 22;
Z.X[0] := 3;
Z.X[1] := 33;
Ref1(X);
WriteLn;
Ref2(Y);
WriteLn;
Ref3(Z);
WriteLn;
Finally
Obj.Free;
End;
End;
{TestAssignment}
{------------------}
VAR
// Global: Reference To Function(CONST Rec: DoubleDouble): DoubleDouble; // ---> E2003 Undeklarierter Bezeichner: 'Reference'
Ref_Global: TMyAnonMethod;
T : DoubleDouble;
Obj_Global: TTest;
Begin
Try
TestAssignment;
// ----> Alle Aufrufe funktionieren
T.X[0] := 4;
T.X[1] := 44;
Ref_Global:= Standalone;
// ----> funktioniert
Ref_Global(T);
WriteLn;
T.X[0] := 5;
T.X[1] := 55;
Obj_Global:= TTest.Create;
Try
Ref_Global:= TTest.OrdinaryMethod;
// error E2010: E2010 Inkompatible Typen: 'TMyAnonMethod' und 'Procedure'
Ref_Global(T);
WriteLn;
ReadLn;
Finally
Obj_Global.Free;
End;
Except
On E:
Exception Do
Writeln(E.ClassName, '
: ', E.
Message);
End;
End.
Läßt sich eine anonyme Methode
ausschließlich von Objekten (Klassen) heraus aufrufen? So wäre das Nix für mich, denn ich bräuchte die Möglichkeit, diese sowohl aus einer stinknormalen Procedur/Function wie aus Klassen heraus aufrufen zu können, ähnlich wie ProzedurPointer und MethodenPointer. (s. #4 (TiGü) und #5).
Oder habe ich die Idee der anonymen Methoden falsch umgesetzt?
Danke & Gruß Andreas