Dışsal Değişken Tuzak Tam olarak nedir? Açıklama ve C# örnekleri takdir edilmektedir.Dış Değişken Tuzak
DÜZENLEME: Jon Skeet en diktayı :) birleştirilmesi
Eric Lippert on the Outer Variable Trap
Dışsal Değişken Tuzak Tam olarak nedir? Açıklama ve C# örnekleri takdir edilmektedir.Dış Değişken Tuzak
DÜZENLEME: Jon Skeet en diktayı :) birleştirilmesi
Eric Lippert on the Outer Variable Trap
bir geliştirici bir değişkenin değeri aslında bir lambda ifadesi veya anonim temsilci tarafından yakalanabilir umduğu "Dış Değişken Tuzak" oluşur değişken kendini yakalar.
Örnek:
var actions = new List<Action>();
for (var i = 0; i < 10; i++)
{
actions.Add(() => Console.Write("{0} ", i));
}
foreach (var action in actions)
{
action();
}
olası çıkış # 1:
0 1 2 3 4 5 6 7 8 9
olası çıkış # 2:
10 10 10 10 10 10 10 10 10 10
halinde 1 numaralı çıkışı beklediniz, Dış Değişken Tuzağına düştünüz. 2 numaralı çıkışı aldın.
Fix:
bir "İç Değişken" Declare defalarca yerine sadece bir kez yakalanır "Dış Değişken" nin çekilecek.
Daha fazla ayrıntı içinvar actions = new List<Action>();
for (var i = 0; i < 10; i++)
{
var j = i;
actions.Add(() => Console.Write("{0} ", j));
}
foreach (var action in actions)
{
action();
}
, ayrıca Eric Lippert's blog görüyoruz.
foreach (var s in strings)
var x = results.Where(r => (r.Text).Contains(s));
gibi
"Tuzak" kelimesi üzerinde ilginç bir kelime: Değişken yakalandı (tuzağa düştün) ve bir sorunla yakalandınız (bir tuzağa düştünüz) –
Bunun kabul edilen cevap olması muhtemel olduğu göz önünde bulundurulduğunda, Eric Lippert'in blog gönderisine bir bağlantı eklemeniz mümkün mü? http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx –
Yani j temelde 'taze' bir değişkendir ve bu nedenle k-th eylemi, loop değişkeninin varsaydığı k-th değerine bağlı bir j_k değişkenini içerir. Sonuç olarak beklenen davranış elde edilir. –
şey her yineleme için yürütülmez içerir çünkü bekliyorsanız sonuçlar verir olmayacak. Döngü içinde geçici bir değişkene atama, bunu düzeltecektir.
'var =' sözdizimine aşina değilim, ne işe yarar? = P – Marc
Nitpick: 'İçerir 'her iterasyon için yürütülür, ancak' s' her zaman aynı değere sahip olacaktır. – dtb
@dtb @Marc Evet, dtb ne dedi. Muhtemelen bu kadar iyi açıklamam. Var sadece dönüş türünü ilan etmek için bir alternatiftir (gerçek kodda aslında buraya dönüş tipini bildirirdim ama bir IDE'nin önünde değilim ve neyin döndüğünü neye benzediğini hissetmedim ... Sanırım onun IEnumberable <>) – heisenberg
@dtb doğru (büyük +1), ancak bunun yalnızca kapağın kapsamı döngü dışında kaldığında geçerli olduğunu unutmayın. Örneğin:
var objects = new []
{
new { Name = "Bill", Id = 1 },
new { Name = "Bob", Id = 5 },
new { Name = "David", Id = 9 }
};
for (var i = 0; i < 10; i++)
{
var match = objects.SingleOrDefault(x => x.Id == i);
if (match != null)
{
Console.WriteLine("i: {0} match: {1}", i, match.Name);
}
}
Bu yazdırır:
i: 1 match: Bill i: 5 match: Bob i: 9 match: David
ReSharper güvenle bu durumda göz ardı edilebilir "modifiye kapatılması, Erişim" konusunda uyaracaktır.
kapanışları kavramını açıklayan Bu makale faydalıdır: Ayrıca
http://en.wikipedia.org/wiki/Closure_(computer_science) bu makale daha spesifik bir C# uygulamasından gerçekten iyidir: Neyse
http://blogs.msdn.com/b/abhinaba/archive/2005/08/08/448939.aspx
, tl lr, değişken kapsam, anonim delege veya lambda ifadelerinde, kodunuzdaki başka herhangi bir yerde olduğu kadar önemlidir - davranış, sadece belli değil.
Bu tuzak şimdi kapatılacak döngü değişkeninin yeni bir kopya her zaman üzerinde foreach
döngüler kapanışları içeride yani C# 5.0 beri çok ama has been changedforeach
döngüler için var olduğunu not etmek layık. Yani aşağıda kodu:
var values = new List<int>() { 100, 110, 120 };
var funcs = new List<Func<int>>();
foreach (var v in values)
funcs.Add(() => v);
foreach (var f in funcs)
Console.WriteLine(f());
Baskılar 120 120 120
< C# 5.0 ancak
100 110 120
> = C# 5.0 Ancak for
döngüler hala aynı şekilde davranır.
Ben googled kadar ne hakkında konuştuğunu hiçbir fikrim yoktu; Bunu yaparken tonlarca açıklama ve örnek buldum (C#), başka ne arıyorsun? – Marc
@Marc Belki OP bu kişilerden biridir (en azından kesin bir şekilde birçok kez söylenir), SO'nun her olası ilgili programlama sorusu için bir yanıtı olmasını ister. Bunun cevabı görünüşte eksikti. –
@Maciej, Mükemmel. Ana liste tamamlanmaya bir adım daha yakın! Web egemenliği, işte geliyoruz! – Marc