C bir döngü içinde yakalanan değişken#
C ile ilgili ilginç bir sorunla karşılaştım#. Aşağıdaki gibi bir kod var.
List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 5)
{
actions.Add(() => variable * 2);
variable;
}
foreach (var act in actions)
{
Console.WriteLine(act.Invoke());
}
Çıkış 0, 2, 4, 6, 8 onu bekliyorum. Ancak, aslında beş 10lu çıkışlar.
Tüm eylemler bir esir değişken atıfta nedeniyle gibi görünüyor. Çağrılan geldiklerinde, sonuç olarak, hepsi aynı çıktı.
Bir şekilde yuvarlak bu sınır her eylem bir örneği ele değişkeni var çalışmam gerek var mı?
CEVAP
- Döngü içinde değişken bir kopyasını almak Evet:
while (variable < 5)
{
int copy = variable;
actions.Add(() => copy * 2);
variable;
}
C gibi düşünebilirsiniz# oluşturur derleyici bir "yeni" yerel değişken bildirimi vurur her zaman. Aslında uygun yeni kapatma nesneleri oluşturmak ve karmaşık (uygulama açısından) eğer birden çok kapsam değişkenleri başvurursanız, çalışıyor ama :) olur
Bu sorun daha sık karşılaşılan bir durumdur for
foreach
kullandığı not:
for (int i=0; i < 10; i ) // Just one variable
foreach (string x in foo) // And again, despite how it reads out loud
C bölümü 7.14.4.2 bu daha fazla ayrıntı için# 3.0 spec, ve benim article on closures Daha fazla örnek de var.
Değişken için döngü içinde bildirilen ...
Önce ya da döngü içinde değişken kavra...
Nasıl GCC kullanılmayan bir değişken b...
Bir döngü içinde bir değişken bildirme...
Deneyin...yakalamak veya bir döngü içi...