Delphi: Pitfalls of Anonymous methods and Capture
Lars Fosdal - 08/Feb2019
Lars Fosdal - 08/Feb2019
[SHOWTOGROUPS=4,20]
I was writing a web request handler when I ran into a problem. I was plugging in multiple handlers, but only one of them actually worked.
Why?
To get to the essence of it, this doesn’t work
Zipped example source code (12/May/2020 online) : Для просмотра ссылки Войдиили Зарегистрируйся
The handler will always be the “bar” handler, probably because it is last.
So, what works? Moving the creating and adding to the list to a separate method.
It behaves the same in both Tokyo and Rio.
Now – here is my question… Is this as expected or a bug ?
Update: The answer is – as expected. The reason is that the capture grabs a reference to the Variable, not to the value of the variable, hence the value of the Variable value will be the same for all captures, and the same as the last value set.
Personally, I would have liked to see the compiler issue a hint or a warning for captures in a loop.
[/SHOWTOGROUPS]
I was writing a web request handler when I ran into a problem. I was plugging in multiple handlers, but only one of them actually worked.
Why?
To get to the essence of it, this doesn’t work
Код:
procedure TMyClass.Setup;
var
Handler: THandlerClass;
hType : THandlers;
begin
Broker.Clear;
for hType in [foo, bar] do
begin
case hType of
foo:
Handler := TFoo.Create;
bar:
Handler := TBar.Create;
end;
Broker.AddHandler(Handler.OnHandle);
end;
end;
Zipped example source code (12/May/2020 online) : Для просмотра ссылки Войди
The handler will always be the “bar” handler, probably because it is last.
So, what works? Moving the creating and adding to the list to a separate method.
Код:
function TMyClass.WithProc<T>: T;
var
Handler: T;
begin
Handler := T.Create;
Broker.AddHandler(Handler.OnHandle);
end;
procedure TMyClass.Setup;
var
hType: THandlers;
begin
Broker.Clear;
for hType in [foo, bar] do
begin
case hType of
foo:
WithProc<TFoo>;
bar:
WithProc<TBar>;
end;
end;
end;
It behaves the same in both Tokyo and Rio.
Now – here is my question… Is this as expected or a bug ?
Update: The answer is – as expected. The reason is that the capture grabs a reference to the Variable, not to the value of the variable, hence the value of the Variable value will be the same for all captures, and the same as the last value set.
Personally, I would have liked to see the compiler issue a hint or a warning for captures in a loop.
[/SHOWTOGROUPS]