दिलचस्प पोस्ट
अत्यधिक अनुकूलित मैट्रिक्स गुणा कोड के लिए एमएसवीसी और जीसीसी के बीच प्रदर्शन में अंतर ASP.NET MVC में एक चेकबॉक्साइलिस्टफ़ोस्ट एक्सटेंशन बनाने के लिए कैसे करें? नीचे के सिवाय रैखिक लेआउट के चारों ओर सीमा कैसे जोड़ती है? jqGrid कस्टम प्रारूप addClass पर विफल रहता है JQuery का उपयोग करने पर असफलता पर AJAX अनुरोध का पुन: प्रयास करने का सबसे अच्छा तरीका क्या है? जावा – कैसे मैक ओएस पर प्रतिलिपि और चिपकाएँ मेनू में हुक क्या मैं एक ही कंप्यूटर पर पायथन 3.x और 2.x को स्थापित कर सकता हूं? धागा में थ्रेड स्टार्ट विधि के लिए पैरामीटर कैसे पारित करें? अजगर प्रोग्राम निष्पादन योग्य बनाने के लिए मैं लिनक्स पर क्या उपयोग करूँ? कोणीय निर्देशों में एक नियंत्रक की आवश्यकता कैसे होती है कांगड़ा 2 में घटना प्रसार रोकें यूटीएफ -8 में 3 बाइट्स से अधिक ले जाने वाले यूनिकोड वर्णों को फ़िल्टर करने (या बदलने के लिए) कैसे करें? बैकस्पेस कुंजी को वापस नेविगेट करने से मैं कैसे रोक सकता हूं? एक स्विच स्टेटमेंट के भीतर चर घोषित करना स्टेक्स या रिकर्सन का उपयोग किए बिना मॉरिस इनरडर ट्री ट्रवर्सल को बताएं

पकड़ के साथ एक कोशिश ब्लॉक के अंदर रिटर्न क्यों नहीं लौटा सकता?

निम्नलिखित ठीक है:

try { Console.WriteLine("Before"); yield return 1; Console.WriteLine("After"); } finally { Console.WriteLine("Done"); } 

finally ब्लॉक तब चलाता है जब पूरी चीज निष्पादित हो गई है ( IEnumerator<T> यह सुनिश्चित करने के लिए एक तरीका प्रदान IDisposable लिए IDisposable समर्थन करता है जब यह समापन समाप्त होने से पहले छोड़ दिया जाता है)।

लेकिन यह ठीक नहीं है:

 try { Console.WriteLine("Before"); yield return 1; // error CS1626: Cannot yield a value in the body of a try block with a catch clause Console.WriteLine("After"); } catch (Exception e) { Console.WriteLine(e.Message); } 

मान लीजिए (तर्क के लिए) कि अपवाद किसी एक या अन्य WriteLine कॉलों द्वारा कोशिश ब्लॉक के अंदर फेंक दिया गया है। catch ब्लॉक में निष्पादन को जारी रखने के साथ क्या समस्या है?

बेशक, उपज रिटर्न का हिस्सा (वर्तमान में) कुछ भी फेंकने में असमर्थ है, लेकिन हमें उस yield return से पहले या बाद में फेंका जाने वाले अपवादों से निपटने के लिए एक संलग्न try / catch लेने से क्यों रोकना चाहिए?

अपडेट: एरिक लिपटर्ट से यहां एक दिलचस्प टिप्पणी है – ऐसा लगता है कि पहले से ही कोशिश / अंत में व्यवहार सही तरीके से लागू करने में पर्याप्त समस्याएं हैं!

संपादित करें: इस त्रुटि पर एमएसडीएन पृष्ठ है: http://msdn.microsoft.com/en-us/library/cs1x15az.aspx यह क्यों नहीं समझाता है, हालांकि।

वेब के समाधान से एकत्रित समाधान "पकड़ के साथ एक कोशिश ब्लॉक के अंदर रिटर्न क्यों नहीं लौटा सकता?"

मुझे संदेह है कि व्यवहार्यता की बजाय व्यावहारिकता का मामला है। मुझे संदेह है कि वहां बहुत ही कम समय हैं, जहां यह प्रतिबंध वास्तव में एक मुद्दा है जो कि आसपास काम नहीं किया जा सकता है – लेकिन संकलक में अतिरिक्त जटिलता बहुत महत्वपूर्ण होगी

इस तरह कुछ ऐसी चीजें हैं जो मैंने पहले ही सामने आई हैं:

  • विशेषताएं सामान्य होने में सक्षम नहीं होती हैं
  • एक्स को XY से प्राप्त करने में असमर्थता (एक्स में नेस्टेड क्लास)
  • जनरेटेड वर्गों में सार्वजनिक क्षेत्रों का उपयोग करने वाले इटरेटर ब्लॉक

इन सभी मामलों में संकलक में अतिरिक्त जटिलता की कीमत पर थोड़ी अधिक आजादी हासिल करना संभव होगा। टीम ने व्यावहारिक पसंद किया, जिसके लिए मैं उन्हें सराहता करता हूं – मुझे 99.9% सही कंपाइलर के साथ थोड़ी अधिक प्रतिबंधात्मक भाषा होती है (हाँ, इसमें कीड़े हैं, मैं सिर्फ दूसरे दिन एक में दौड़ता था) और अधिक लचीला भाषा जो सही ढंग से संकलित नहीं हो सकती

संपादित करें: यहां एक छद्म सबूत है कि यह क्यों संभव है कि यह क्यों संभव है।

उस पर विचार करे:

  • आप यह सुनिश्चित कर सकते हैं कि उपज रिटर्न का हिस्सा खुद अपवाद नहीं डालता (मूल्य का अनुमान लगाने से पहले, और फिर आप सिर्फ एक फ़ील्ड सेट कर रहे हैं और "सत्य" लौट रहे हैं)
  • आपको अनुमति / पकड़ की अनुमति दी गई है जो इटरेटर ब्लॉक में उपज रिटर्न का उपयोग नहीं करता है।
  • इटरेटर ब्लॉक में सभी स्थानीय चर उत्पन्न प्रकार में उदाहरण चर हैं, ताकि आप कोड को नए तरीकों पर स्वतंत्र रूप से स्थानांतरित कर सकें

अब रूपांतरण:

 try { Console.WriteLine("a"); yield return 10; Console.WriteLine("b"); } catch (Something e) { Console.WriteLine("Catch block"); } Console.WriteLine("Post"); 

(छद्म कोड की तरह) में:

 case just_before_try_state: try { Console.WriteLine("a"); } catch (Something e) { CatchBlock(); goto case post; } __current = 10; return true; case just_after_yield_return: try { Console.WriteLine("b"); } catch (Something e) { CatchBlock(); } goto case post; case post; Console.WriteLine("Post"); void CatchBlock() { Console.WriteLine("Catch block"); } 

एकमात्र अनुलिपि में प्रयास / पकड़ने वाले ब्लॉक स्थापित करने में है – लेकिन ऐसा कुछ है जो कंपाइलर निश्चित तौर पर कर सकता है।

मुझे यहाँ कुछ याद हो सकता है – यदि हां, तो कृपया मुझे बताएं!

इटरेटर परिभाषा में सभी yield बयान राज्य मशीन में एक राज्य में परिवर्तित हो जाते हैं जो राज्यों को अग्रिम करने के लिए एक switch स्टेटमेंट का उपयोग करता है। अगर उसने कोशिश / पकड़ में yield बयान के लिए कोड उत्पन्न किया है, तो उस खंड के लिए प्रत्येक अन्य yield विवरण को छोड़कर प्रत्येक yield विवरण के लिए try ब्लॉक में सब कुछ डुप्लिकेट करना होगा। यह हमेशा संभव नहीं होता है, खासकर यदि एक yield बयान पहले के एक पर निर्भर होता है

मुझे लगता है कि जिस तरह से कॉल स्टैक एक घाव से वापस लौटते समय गले / गड़बड़ हो जाता है, इसलिए यह कोशिश करता है / पकड़ ब्लॉक के लिए वास्तव में अपवाद को पकड़ने के लिए असंभव हो जाता है। (क्योंकि उपज रिटर्न ब्लैक स्टैक पर नहीं है, भले ही वह चलना ब्लॉक बना रहा हो)

मैं एक इटरेटर ब्लॉक सेटअप और उस इरेटरेटर का उपयोग करके एक फोरहैक के बारे में क्या बात कर रहा हूं, इसके बारे में एक विचार प्राप्त करने के लिए जांचें कि कॉल स्टैक को फोरछा ब्लॉक के अंदर कैसा दिखता है और फिर इटरेटर के अंदर इसे जांचें / अंत में ब्लॉक करें।

मैंने इनवेंसिली स्केईट के उत्तर को स्वीकार कर लिया है जब तक माइक्रोसॉफ्ट से कोई व्यक्ति इस विचार पर ठंडे पानी डालने के लिए नहीं आता है। लेकिन मैं मामले के राय से सहमत नहीं हूं – निश्चित रूप से एक सही संकलक एक पूर्णांक से ज़्यादा महत्वपूर्ण है, लेकिन सी # संकलक पहले से बहुत ही चतुर है, जहां तक ​​हमारे लिए यह परिवर्तन हो रहा है। इस मामले में थोड़ी अधिक पूर्णता कम बढ़त वाले मामलों या बट्टों के साथ भाषा को उपयोग, सिखाने, समझाने में आसान बनाती है। इसलिए मुझे लगता है कि यह अतिरिक्त प्रयास के लायक होगा। रेडमंड के कुछ लोग पखवाड़े के लिए अपने सिर खरोंचते हैं, और नतीजतन अगले दशक में लाखों कोडर थोड़ा आराम कर सकते हैं।

(मैं भी वहां एक अपरिहार्य बनाने के लिए एक सख्त इच्छा रखता हूं जो कि एक अपवाद फेंकता है जो कोड के चलते ड्राइविंग द्वारा "बाहर से" राज्य मशीन में भर गया है। लेकिन इसके लिए मेरे कारण काफी अस्पष्ट हैं ।)

असल में एक प्रश्न मैं जॉन के जवाब के बारे में है कि उपज रिटर्न एक्सप्रेशन फेंकता है।

जाहिर है 10 रिटर्न उपज 10 इतना बुरा नहीं है लेकिन यह बुरा होगा:

 yield return File.ReadAllText("c:\\missing.txt").Length; 

तो इससे पूर्ववर्ती प्रयास / पकड़ ब्लॉक के अंदर इसका मूल्यांकन करने के लिए अधिक समझ नहीं होगी:

 case just_before_try_state: try { Console.WriteLine("a"); __current = File.ReadAllText("c:\\missing.txt").Length; } catch (Something e) { CatchBlock(); goto case post; } return true; 

अगली समस्या को नेस्ट किया जाएगा / ब्लॉकों को पकड़ने और पुनः अपवाद अपवादों की कोशिश की जाएगी:

 try { Console.WriteLine("x"); try { Console.WriteLine("a"); yield return 10; Console.WriteLine("b"); } catch (Something e) { Console.WriteLine("y"); if ((DateTime.Now.Second % 2) == 0) throw; } } catch (Something e) { Console.WriteLine("Catch block"); } Console.WriteLine("Post"); 

लेकिन मुझे यकीन है कि यह संभव है …

एकता का उपयोग करने वालों के लिए:

 yield return new WaitForSeconds(startWait); while (numWaves < 4 && _myPauseState) { for (int i = 0; i < hazardCount;) { //spawn code } yield return new WaitForSeconds(waveWait); numWaves++; } 

वास्तव में एक ienumerator के अंदर संभव है