दिलचस्प पोस्ट
Google मैप्स और रिचफेस 3.3.3 (प्रोटोटाइप.जेएस 1.6.0.3) संभव असंगति जावास्क्रिप्ट में एक फ़ाइल से दूसरे को चर कैसे भेजना है? मैं दो जावास्क्रिप्ट ऑब्जेक्ट ग्राफ़ के बीच के अंतरों की एक सूची कैसे प्राप्त करूं? घातक त्रुटि: स्विफ्ट 2.0 के साथ किसी स्थान को स्वैप करने का समर्थन नहीं किया गया है मैं iOS ऐप पर कस्टम कुंजीपटल से कीस्ट्रोक्स कैसे प्राप्त करूं? एक फाइल को sdcard में लिखना PHP में सबसे तेज़ XML पार्सर क्या है? घटनाओं के फटने को सुचारू बनाने के लिए आरएक्स IObservable बफरिंग स्विंग प्रतिपादन जेडीके 1.8 में टूट गया, जेडीके 1.7 में सही है जावा: प्रिंटस्ट्रीम और प्रिंटवेयर के बीच का अंतर आईओएस 8 कस्टम कीबोर्ड: ऊँचाई बदलना स्टोरीबोर्ड लॉन्ग स्क्रीन के लिए सर्वोत्तम प्रथाएं, लॉगआउट पर डेटा के समाशोधन को संभालने जाओ और Node.js HTTP सर्वर के साथ एक एकल कुकी सेट करें SSL_connect = = errno = 0 state = SSLv3 पढ़ा सर्वर प्रमाण पत्र बी: प्रमाण पत्र सत्यापित करने में विफल SSL कनेक्शन स्थापित करने में असमर्थ, मैं अपने एसएसएल प्रमाणपत्र को कैसे तय करूं?

लम्बा लूप में चर कैप्चर – यहाँ क्या होता है?

मैं अपने सिर के आसपास की कोशिश कर रहा हूँ, यहाँ क्या होता है? कम्पाइलर का किस तरह का कोड है?

public static void vc() { var listActions = new List<Action>(); foreach (int i in Enumerable.Range(1, 10)) { listActions.Add(() => Console.WriteLine(i)); } foreach (Action action in listActions) { action(); } } static void Main(string[] args) { vc(); } 

आउटपुट: 10 10 .. 10

इसके अनुसार, एक्शन हेल्पर का एक नया उदाहरण प्रत्येक पुनरावृत्त के लिए बनाया जाएगा। तो उस मामले में, मुझे लगता होगा कि यह प्रिंट 1..10 होगा। क्या कोई मुझे कंपाइलर यहाँ क्या कर रहा है की कुछ छद्म कोड दे सकता है?

धन्यवाद।

Solutions Collecting From Web of "लम्बा लूप में चर कैप्चर – यहाँ क्या होता है?"

इस लाइन में

  listActions.Add(() => Console.WriteLine(i)); 

चर i , कब्जा कर लिया है, या यदि आप चाहें, तो उस चर के स्मृति स्थान पर एक सूचक बनाया। इसका अर्थ है कि प्रत्येक प्रतिनिधि को उस मेमोरी स्थान पर एक सूचक मिला है। इस लूप निष्पादन के बाद:

 foreach (int i in Enumerable.Range(1, 10)) { listActions.Add(() => Console.WriteLine(i)); } 

स्पष्ट कारणों के लिए i 10 , इसलिए मेमोरी सामग्री जो कि Action (एस) में मौजूद सभी बिंदुओं की ओर इशारा करते हैं, 10 हो जाती हैं।

दूसरे शब्दों में, i कब्जा कर लिया है।

वैसे, ध्यान दें, कि एरिक लिपर्ट के अनुसार, यह "अजीब" व्यवहार C# 5.0 में हल किया जाएगा।

तो C# 5.0 आपका प्रोग्राम अपेक्षित रूप से प्रिंट करेगा:

 1,2,3,4,5...10 

संपादित करें:

विषय पर एरिक लिपर्ट की पोस्ट नहीं मिल सकती, लेकिन यहां एक और है:

लूप में बंद होने पर रिजिट किया गया

कम्पाइलर का किस तरह का कोड है?

ऐसा लगता है जैसे आप यह उम्मीद करते हैं:

 foreach (int temp in Enumerable.Range(1, 10)) { int i = temp; listActions.Add(() => Console.WriteLine(i)); } 

यह प्रत्येक पुनरावृत्ति के लिए एक अलग varaible का उपयोग करता है, और इसलिए लैम्ब्डा बनाए जाने के समय चर के मूल्य पर कब्जा कर लिया जाएगा। असल में, आप इस सटीक कोड का इस्तेमाल कर सकते हैं और परिणाम आप चाहते हैं।

लेकिन वास्तव में संकलक वास्तव में क्या करता है:

 int i; foreach (i in Enumerable.Range(1, 10)) { listActions.Add(() => Console.WriteLine(i)); } 

इससे यह साफ हो जाता है कि आप प्रत्येक चलना पर एक ही चर पर कब्जा कर रहे हैं। जब आप बाद में जाते हैं और वास्तव में उस कोड को निष्पादित करते हैं, तो वे सभी उसी मूल्य का उल्लेख करते हैं जो पहले से 10 तक बढ़ा है।

यह संकलक या रनटाइम में एक बग नहीं है … यह भाषा डिजाइन टीम के एक सचेत निर्णय था। हालांकि, यह कैसे काम करता है, इस बारे में भ्रम के कारण, उन्होंने इस निर्णय को उलट कर दिया है और सी # 5 के लिए उम्मीद की तरह काम करने के लिए इसे तोड़ने के बदलाव के जोखिम का फैसला किया है ।

संक्षेप में क्या हो रहा है कि संकलक आपके int i को लूप के बाहर घोषित कर रहा है और इस प्रकार हर एक्शन के लिए इसका नया मान नहीं बना रहा है, केवल हर बार उसी को संदर्भित करता है जब तक आप कोड को निष्पादित कर लेते हैं I 10 है और इसलिए यह बहुत कम 10 प्रिंट करता है।