Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign an overloaded class method to anonymous method?

Tags:

delphi

In Delphi, we can assign a class method (declared as procedure of object) as parameter of type anonymous method.

For overloaded methods (same method names), passing the object method fail with compilation error:

[dcc32 Error] Project56.dpr(40): E2010 Incompatible types: 'System.SysUtils.TProc<System.Integer,System.Integer>' and 'Procedure of object'

The following example show the situation. Is that possible to let the overloaded method pass as anonymous method parameter?

type
  TTest = class
  public
    procedure M(a: Integer); overload;
    procedure M(a, b: Integer); overload;
  end;

procedure TTest.M(a, b: Integer);
begin
  WriteLn(a, b);
end;

procedure TTest.M(a: Integer);
begin
  WriteLn(a);
end;

procedure DoTask1(Proc: TProc<Integer>);
begin
  Proc(100);
end;

procedure DoTask2(Proc: TProc<Integer,Integer>);
begin
  Proc(100, 200);
end;

begin
  var o := TTest.Create;
  DoTask1(o.M);  // <-- Success
  DoTask2(o.M);  // <-- Fail to compile: E2010 Incompatible types: 'System.SysUtils.TProc<System.Integer,System.Integer>' and 'Procedure of object'
  ReadLn;
end.
like image 399
Chau Chee Yang Avatar asked Aug 28 '19 05:08

Chau Chee Yang


1 Answers

When you write

DoTask2(o.M);

The compiler sees that o.M is not an anonymous method, and generates one for you behind the scenes, that wraps the call to o.M. Unfortunately it's not able to search overloaded methods when doing this, hence the compile error.

The solution is to manually generate the anonymous method wrapper.

DoTask2(
  procedure(a, b: Integer) 
  begin
    o.M(a, b);
  end 
);

This is exactly what the compiler is doing for you behind the scenes when it wraps a standard method with an anonymous method. So whilst the syntax is tiresome, the end result is identical at runtime.

like image 68
David Heffernan Avatar answered Nov 13 '22 01:11

David Heffernan