El delegado de acción utiliza los últimos valores de las variables declaradas fuera del bucle foreach

Tengo este pedazo de código:

int i = 0;
foreach(var tile in lib.dic.Values)
{
    var ii = i;
    var t = tile;
    Button b = new Button( () = > { MainStatic.tile = t; } );
    Checkbox c = new Checkbox( () = > { lib.arr[ii].b = !lib.arr[ii].b; } );
    i++;
}

Mientras que el código anterior funciona como debería, esta pieza a continuación:

int i = 0;
foreach(var tile in lib.dic.Values)
{
    Button b = new Button( () = > { MainStatic.tile = tile; } );
    Checkbox c = new Checkbox( () = > { lib.arr[i].b = !lib.arr[i].b; } );
    i++;
}

… Siempre se ejecutarán los delegados con los últimos valores dei ytile variables ¿Por qué sucede esto y por qué tengo que hacer una copia local de esas vars, especialmente el tipo sin referencia?int i?

Respuestas a la pregunta(3)

Su respuesta a la pregunta