Chau Chee Yang
Chau Chee Yang

Reputation: 19700

How to assign an overloaded class method to anonymous method?

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.

Upvotes: 14

Views: 587

Answers (1)

David Heffernan
David Heffernan

Reputation: 613612

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.

Upvotes: 17

Related Questions