2
See this code to better understand:
using static System.Console;
using System;
using System.Collections.Generic;
public class Program {
public static void Main() {
var lista = new List<Action>();
for (var i = 0; i < 10; i++) lista.Add(() => WriteLine(i));
for (var c = 0; c < 10; c++) Metodo(lista[c]);
var lista2 = new List<Action>();
for (var i = 0; i < 10; i++) {
var tmp = i;
lista2.Add(() => WriteLine(tmp));
}
for (var c = 0; c < 10; c++) Metodo(lista2[c]);
}
public static void Metodo(Action func) => func();
}
Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.
Before you see it running, what do you expect to happen? Print the numbers from 0 to 1? That’s what you’re warning. You probably expect something that will not happen. This code will print 10 times the number 10 which is the last value of i
, the variable captured in lambda. It may be what you want, but it’s unlikely.
The solution is to create an intermediate variable just to support the lambda and the capture occurs correctly. Thus:
var lista2 = new List<Action>();
for (var i = 0; i < 10; i++) {
var tmp = i;
lista2.Add(() => WriteLine(tmp));
}
for (var c = 0; c < 10; c++) {
Metodo(lista2[c]);
}
The error messages are:
Closures implicitly captured
This problem is related to the fact that a reference has been captured by the anonymous function and will survive longer than it should and it is good you know well what you are doing, this can cause a memory leak
Access to a modified closure
Used a captured variable that does not have the most likely desired value
Could explain what the terms mean
Implicitly captured closures
orAcess to modified closure
?– rubStackOverflow
Only the translation?.
– Maniero
The translation and an explanation I could not understand what exactly this term means, I think online translators are translating 'to the letter' =/
– rubStackOverflow