Delegado de ação usa os últimos valores de variáveis ​​declaradas fora do loop foreach

Eu tenho este pedaço 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++;
}

Enquanto o código acima funciona como deveria, esta parte abaixo:

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++;
}

… Sempre executará os delegados com os últimos valores dei etile variáveis. Por que isso acontece e por que eu tenho que fazer uma cópia local dessas variáveis, especialmente do tipo não referênciaint i?

questionAnswers(3)

yourAnswerToTheQuestion