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]);
}
}
public static void Metodo(Action func) {
func();
}
}
See working at dotNetFiddle and CodingGround .
Before you see it running, what do you expect to happen? Who prints 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 that's what you want, but it's unlikely.
The solution is to create an intermediate variable just to support lambda and capture takes place correctly. So:
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 was captured by the anonymous function and will survive more than it should and it is good that you know well what it is doing, this can cause a memory leak
Access to a modified closure
Used a captured variable that does not have the value likely to be