I\'m trying to build an custom comparer which allows the assignment of the comparison function to an internal field. In order to ease the creation of the comparer, I tried t
The compiler error on my English Delphi reads:
[dcc32 Error] E2555 Cannot capture symbol 'Result'
This is due to a defective design. There's no reason for any variable capture to be taking place here at all. The right hand side of the assignment is an instance method rather than an anonymous method. But the compiler handles that by wrapping the method in an anonymous method. The compiler translates
Result.FVar := Result.CompareInternal;
to
Result.FVar :=
function(const Arg1, Arg2: string): Integer
begin
InnerResult := OuterResult.CompareInternal(Arg1, Arg2);
end;
Leaving aside the confusion over the two separate result variables, the compiler rejects this because the outer result variable is not a local, it's a var parameter. And so cannot be captured.
But the whole design is wrong in my view. There's no need for any variable capture. When you write Result.CompareInternal you intend to refer to a normal of object method. With a better design, the compiler would allow this assignment without creating an anonymous method.
You can work around the problem like this:
class function TDemo.Construct: TDemo;
var
Demo: TDemo;
begin
Demo := TDemo.Create();
Demo.FVar := Demo.CompareInternal;
Result := Demo;
end;
Here the local variable Demo can be captured.
Or as I would suggest, like this:
program ConsoleDemo1;
{$APPTYPE CONSOLE}
uses
Generics.Defaults,
System.SysUtils;
type
TConstFunc = reference to function(const Arg1: T1;
const Arg2: T2): TResult;
TDemo = class(TComparer)
private
FVar: TConstFunc;
function CompareInternal(const L, R: string): Integer;
public
constructor Create;
function Compare(const L, R: string): Integer; override;
end;
constructor TDemo.Create;
begin
inherited;
FVar := CompareInternal;
end;
function TDemo.Compare(const L, R: string): Integer;
begin
Result := FVar(L, R);
end;
function TDemo.CompareInternal(const L, R: string): Integer;
begin
Result := AnsiCompareStr(L, R);
end;
end.