I'm attempting to translate a small library that was written by a coworker in C# into Delphi. It relies heavily on generics and anonymous methods.
I'm attempting to translate a small library that was written by a coworker in C# into Delphi. It relies heavily on generics and anonymous methods.
I'm having issues attempting to pass an anonymous function as an argument to a procedure. I have code that looks like:
procedure TSomeObject.SomeProc(callback: TFunc);
The code that calls this procedure looks like:
someObject.SomeProc(
function(in: string):Integer
begin
if Assigned(in) then
Result := 1;
end);
But the compiler just gives me:
E2010 Incompatible types: 'System.SysUtils.TFunc>' and 'Procedure'
I've tried adding explicit type parameters. I've tried making the anonymous method an ordinary method and a stand alone function. Still get the same error message just a different type for the second operand. When I made it an object method it said the second type was 'Procedure of object' instead.
Anyone have a clue what I'm doing wrong?
I'm having issues attempting to pass an anonymous function as an argument to a procedure. I have code that looks like:
procedure TSomeObject.SomeProc
The code that calls this procedure looks like:
someObject.SomeProc(
function(in: string):Integer
begin
if Assigned(in) then
Result := 1;
end);
But the compiler just gives me:
E2010 Incompatible types: 'System.SysUtils.TFunc
I've tried adding explicit type parameters. I've tried making the anonymous method an ordinary method and a stand alone function. Still get the same error message just a different type for the second operand. When I made it an object method it said the second type was 'Procedure of object' instead.
Anyone have a clue what I'm doing wrong?
/sub
ReplyDeleteis there a parameter prefix in the declaration of TFunc?
ReplyDeletei.e.
type
TFunc = reference to function(const aValue:T1):T2;
if so,
someObject.SomeProc(
function(const in: string):Integer
begin
if Assigned(in) then
Result := 1;
end);
It's the TFunc defined in SysUtils:
ReplyDeleteTFunc = reference to function (Arg1: T): TResult;
I don't see anything out of the ordinary. Do you?
Also - Assigned on a string is a bit unusual - at least for me ;)
ReplyDeleteI just added that to fill space. I probably should have just wrote:
ReplyDelete//Do Something
in the function body.
Wait a sec.
ReplyDeleteprocedure TSomeObject.SomeProc(callback: TFunc);
Are T1 and T2 part of the TSomeObject?
i.e. TSomeObject ?
If not, your call needs to be
someObject.SomeProc(
function(const in: string):Integer
begin
if Assigned(in) then
Result := 1;
end);
Lars Fosdal
ReplyDeleteWell Delphi's type inference should make that unnecessary but as I said in the OP I've already tried adding explicit type parameters. No dice.
// Compiles and runs in XE 7.1
ReplyDeleteprogram GenericsTypeInference;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TSomeObject = class
procedure SomeProc(callback: TFunc);
end;
{ TSomeObject }
procedure TSomeObject.SomeProc(callback: TFunc);
begin
// Do something
end;
var
SomeObject : TSomeObject;
begin
try
SomeObject := TSomeObject.Create;
try
SomeObject.SomeProc< String, Integer >(function(arg: string):Integer
begin
Result := 0;
end);
finally
SomeObject.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
SomeObject.SomeProc(function(arg: string):Integer
ReplyDeletebegin
Result := 0;
end);
fails.
Type inference only works directly on arguments of the generic type. It does not look into compound types.
ReplyDeleteOk. Didn't realize type inference was so limited in Delphi. The example I posted was simplified a little too much. The production code had much more complicated type parameters. Like:
ReplyDelete>>
When inference didn't work I accidently transposed one of the type parameters when I attempted to fill them in at the call site.
The error message identifying the right operand as simply 'procedure' is pretty useless for troubleshooting. If it had been expanded the way the left one was I probably would have noticed the problem sooner.