Değiştirilen kapamaya erişim

 string [] files = new string[2]; files[0] = "ThinkFarAhead.Example.Settings.Configuration_Local.xml"; files[1] = "ThinkFarAhead.Example.Settings.Configuration_Global.xml"; //Resharper complains this is an "access to modified closure" for (int i = 0; i < files.Length; i++ ) { // Resharper disable AccessToModifiedClosure if(Array.Exists(Assembly.GetExecutingAssembly().GetManifestResourceNames(), delegate(string name) { return name.Equals(files[i]); })) return Assembly.GetExecutingAssembly().GetManifestResourceStream(files[i]); // ReSharper restore AccessToModifiedClosure } 

Her ne kadar ReSharper, bunun “değiştirilmiş bir kapatmaya erişim” olduğundan şikayet etmesine rağmen, yukarıda belirtilenlerin işe yaramadığı görülüyor. Birisi buna ışık tutabilir mi?

(bu konu burada devam etti)

277
25 окт. 25 Ekim tarihinde Vyas Bharghava tarafından set 2008-10-25 01:18 '08, 1:18 2008-10-25 01:18
@ 3 cevaplar

Bu durumda, bu normaldir çünkü gerçekte temsilciyi bir döngüde yürütüyorsunuz.

Bununla birlikte, temsilciyi kaydedip daha sonra kullanırsanız, [i] dosyalarına erişmeye çalışırken tüm delegelerin istisnalar atacağını göreceksiniz - delegelerin oluşturulması sırasında değeri değil, i değişkenini yakalarlar.

Kısacası, potansiyel bir tuzak olarak bilmeniz gereken şey budur, ancak bu durumda size zarar vermeyecektir.

Sonuçların mantıksız olduğu daha karmaşık bir örnek için bu sayfanın en altına bakın.

283
25 окт. Cevapla Jon Skeet 25 Eki 2008-10-25 01:20 '08, 1:20 2008-10-25 01:20

Bunun eski bir soru olduğunu biliyorum ama yakın zamanda kapatılmayı ve örnek kodun yararlı olabileceğini düşündüm. Sahnelerin arkasında, derleyici, bir işlev çağrısı için sözcüksel kapanışı temsil eden bir sınıf oluşturur. Muhtemelen böyle bir şey görünüyor:

 private sealed class Closure { public string[] files; public int i; public bool YourAnonymousMethod(string name) { return name.Equals(this.files[this.i]); } } 

Yukarıda bahsedildiği gibi, fonksiyonunuz işe yarıyor, çünkü tahminler yaratıldıktan hemen sonra çağrılıyor. Derleyici şöyle bir şey üretecektir:

border=0
 private string Works() { var closure = new Closure(); closure.files = new string[3]; closure.files[0] = "notfoo"; closure.files[1] = "bar"; closure.files[2] = "notbaz"; var arrayToSearch = new string[] { "foo", "bar", "baz" }; //this works, because the predicates are being executed during the loop for (closure.i = 0; closure.i < closure.files.Length; closure.i++) { if (Array.Exists(arrayToSearch, closure.YourAnonymousMethod)) return closure.files[closure.i]; } return null; } 

Öte yandan, tahminleri kaydetmeniz ve ardından çağrı bildirmeleri yapmanız durumunda, tahminlere yapılan her çağrının aslında kapatma sınıfının bir örneğinde aynı yöntemi arayacağını ve bu nedenle, i için aynı değeri kullanacağını göreceksiniz.

23
29 марта '13 в 20:31 2013-03-29 20:31 Cevap gerrard00 29 Mart 13: 20: 31'te 2013-03-29 20:31

"files" yakalanmış bir harici değişkendir, çünkü isimsiz bir temsilcinin işlevi tarafından yakalanmıştır. Ömrü, isimsiz delege işlevi ile uzatılır.

Yakalanan Harici Değişkenler Harici bir değişken isimsiz bir işlevi ifade ettiğinde, harici değişkenin isimsiz bir işlev tarafından yakalandığı düşünülür. Tipik olarak, bir yerel değişkenin ömrü, ilişkili olduğu bloğun veya işlecin yürütülmesi ile sınırlıdır (yerel değişkenler). Bununla birlikte, yakalanan bir harici değişkenin ömrü en azından anonim işlevden oluşturulan delege ağacı veya ifade ağacı çöp toplama için uygun hale gelinceye kadar artar.

https://docs.microsoft.com/en-us/dotnet/csharp/>

Yerel bir değişken veya parametre değeri anonim bir işlev tarafından yakalandığında, yerel değişken veya parametre artık sabit bir değişken (sabit ve hareketli değişkenler) olarak kabul edilmez, bunun yerine mobil olarak kabul edilir. Bu nedenle, yakalanan bir dış değişkenin adresini alan güvenli olmayan herhangi bir kodun önce değişkeni işlemek için sabit bir ifade kullanması gerekir. Yüklenmemiş bir değişkenin aksine, yakalanan bir yerel değişkenin aynı anda birden fazla iş parçacığından etkilenebileceğini unutmayın.

14 авг. Cevap Chris hu 14 Ağustos tarafından verilir . 2017-08-14 02:17 '17, 02:17 2017-08-14 02:17

Etiketler hakkındaki diğer sorular veya Soru Sor