दिलचस्प पोस्ट
बहु-आयामी सरणी से डेटा को लागू करें आप एक स्क्रिप्ट प्रोफ़ाइल कैसे कर सकते हैं? Xcode 6: कीबोर्ड सिम्युलेटर में दिखाई नहीं देता टोमकैट पर ईजेबी आधारित एप्लिकेशन को कैसे लागू किया जाए सक्रिय रेकर्ड में फ्लोट बनाम दशमलव Urllib, urllib2 और अनुरोध मॉड्यूल के बीच अंतर क्या हैं? ब्राउज़र के माध्यम से कैमरा पहुंच जावा बहु-थ्रेडिंग और सुरक्षित प्रकाशन जावास्क्रिप्ट: मैं JSONP कैसे बनाऊँ? स्थानीय आईपी पता प्राप्त करें क्या आप अपने वाणिज्यिक जावा कोड को अस्पष्ट करते हैं? जावास्क्रिप्ट में हर एन वर्ण के बाद मैं एक चरित्र कैसे सम्मिलित कर सकता हूं? अजगर में ओवरलोडिंग ऑपरेटर आईओएस में कीबोर्ड दिखाई देने पर UIView ऊपर जाएं एक int पर आधारित एकाधिक संख्याबद्ध चर बनाएँ

क्यों सी # में एक अपवाद पकड़ और rethrow?

मैं लेख सी # पर देख रहा हूं धारावाहिक डीटीओ पर डेटा स्थानांतरण ऑब्जेक्ट

आलेख में कोड का यह टुकड़ा शामिल है:

public static string SerializeDTO(DTO dto) { try { XmlSerializer xmlSer = new XmlSerializer(dto.GetType()); StringWriter sWriter = new StringWriter(); xmlSer.Serialize(sWriter, dto); return sWriter.ToString(); } catch(Exception ex) { throw ex; } } 

लेख के बाकी समझदार और उचित (एक noob के लिए) दिखता है, लेकिन यह कोशिश-पकड़-फेंक एक WtfException फेंकता है … यह बिल्कुल बिल्कुल अपवाद नहीं हैंडलिंग के समान है?

Ergo:

 public static string SerializeDTO(DTO dto) { XmlSerializer xmlSer = new XmlSerializer(dto.GetType()); StringWriter sWriter = new StringWriter(); xmlSer.Serialize(sWriter, dto); return sWriter.ToString(); } 

या मैं सी # में त्रुटि से निपटने के बारे में कुछ बुनियादी याद कर रहा हूँ? यह बहुत जावा के समान है (कम से कम अपवादों की जांच), है ना? … यही है, वे दोनों परिष्कृत सी ++

स्टैक अतिप्रवाह प्रश्न पैरामीटर-कम पकड़ने और कुछ भी नहीं करने के बीच फेंकने में अंतर है? मेरी विवाद का समर्थन करते हुए लगता है कि पकड़-फेंक की कोशिश है-कोई नो-ऑप।


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

भविष्य में इस धागे को ढूंढने वाले किसी के लिए संक्षेप में बस …

ऐसा न करें

 try { // Do stuff that might throw an exception } catch (Exception e) { throw e; // This destroys the strack trace information! } 

स्टैक ट्रेस जानकारी समस्या के मूल कारण की पहचान करने के लिए महत्वपूर्ण हो सकती है!

कर

 try { // Do stuff that might throw an exception } catch (SqlException e) { // Log it if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound. // Do special cleanup, like maybe closing the "dirty" database connection. throw; // This preserves the stack trace } } catch (IOException e) { // Log it throw; } catch (Exception e) { // Log it throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java). } finally { // Normal clean goes here (like closing open files). } 

कम विशिष्ट वाले (जैसे जावा) से पहले अधिक विशिष्ट अपवादों को पकड़ो।


संदर्भ:

वेब के समाधान से एकत्रित समाधान "क्यों सी # में एक अपवाद पकड़ और rethrow?"

प्रथम; जिस तरह से लेख में कोड करता है वह बुराई है throw ex कॉल स्टैक को उस बिंदु पर रीसेट करेगा जहां यह फेंक देना वक्तव्य है; अपवाद वास्तव में बनाया गया था जहां के बारे में जानकारी खोने

दूसरा, यदि आप बस उस तरह पकड़ और फिर से फेंकते हैं, तो मुझे कोई अतिरिक्त मूल्य नहीं मिल रहा है, ऊपर दिए गए कोड का उदाहरण, कोशिश-पकड़ के बिना बस के रूप में अच्छा होगा (या, थोड़ी सी throw ex दी जाएगी, यहां तक ​​कि बेहतर)।

हालांकि, ऐसे मामले हैं जहां आप अपवाद को पकड़ने और पुनः स्थापित करना चाहते हैं। लॉगिंग उनमें से एक हो सकता है:

 try { // code that may throw exceptions } catch(Exception ex) { // add error logging here throw; } 

ऐसा मत करो,

 try { ... } catch(Exception ex) { throw ex; } 

आप स्टैक ट्रेस जानकारी खो देंगे …

या तो करो,

 try { ... } catch { throw; } 

या

 try { ... } catch (Exception ex) { throw new Exception("My Custom Error Message", ex); } 

एक कारण है जिसे आप पुनर्स्थापित करना चाहते हैं, यदि आप अलग-अलग अपवादों को संभालना चाहते हैं, उदाहरण के लिए

 try { ... } catch(SQLException sex) { //Do Custom Logging //Don't throw exception - swallow it here } catch(OtherException oex) { //Do something else throw new WrappedException("Other Exception occured"); } catch { System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack"); throw; //Chuck everything else back up the stack } 

सी # (सी # 6 से पहले) सीआईएल "फ़िल्टर्ड अपवाद" का समर्थन नहीं करता है, जो वीबी करता है, इसलिए सी # 1-5 में एक अपवाद फेंकने का एक कारण है कि पकड़ने के समय आपके पास पर्याप्त जानकारी नहीं है यह निर्धारित करने के लिए कि क्या आप वास्तव में अपवाद को पकड़ना चाहते थे।

उदाहरण के लिए, वीबी में आप ऐसा कर सकते हैं

 Try .. Catch Ex As MyException When Ex.ErrorCode = 123 .. End Try 

… जो अलग-अलग ErrorCode मानों के साथ MyExceptions को नियंत्रित नहीं करेगा I सी # में v6 से पहले, यदि आपको त्रुटि कोड 123 नहीं है तो आपको माइएक्सेशन को पकड़ना और फिर से फेंक करना होगा:

 try { ... } catch(MyException ex) { if (ex.ErrorCode != 123) throw; ... } 

चूंकि सी # 6.0 आप वीबी के साथ ही फ़िल्टर कर सकते हैं :

 try { // Do stuff } catch (Exception e) when (e.ErrorCode == 123456) // filter { // Handle, other exceptions will be left alone and bubble up } 

अपवादों को पुनर्स्थापित करने का एक वैध कारण यह हो सकता है कि आप अपवाद को जानकारी जोड़ना चाहते हैं, या शायद अपनी किसी एक बनाने में मूल अपवाद लपेटते हैं:

 public static string SerializeDTO(DTO dto) { try { XmlSerializer xmlSer = new XmlSerializer(dto.GetType()); StringWriter sWriter = new StringWriter(); xmlSer.Serialize(sWriter, dto); return sWriter.ToString(); } catch(Exception ex) { string message = String.Format("Something went wrong serializing DTO {0}", DTO); throw new MyLibraryException(message, ex); } } 

जैसे कोड रखने का मेरा मुख्य कारण:

 try { //Some code } catch (Exception e) { throw; } 

तो मैं पकड़ में एक ब्रेकपॉइंट हो सकता है, जिसमें एक तत्काल अपवाद ऑब्जेक्ट है। विकास / डिबगिंग करते समय मैं यह बहुत कुछ करता हूं बेशक, कंपाइलर मुझे सभी अप्रयुक्त ई पर चेतावनी देता है, और आदर्श रूप से उन्हें रिलीज़ बिल्ड से पहले हटा दिया जाना चाहिए।

हालांकि डीबगिंग के दौरान ये अच्छे होते हैं

यह बिल्कुल बिल्कुल अपवाद नहीं हैंडलिंग के समान है?

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

आप पूर्व फेंकना नहीं चाहते – क्योंकि यह कॉल स्टैक खो देगा। अपवाद हैंडलिंग देखें (एमएसडीएन)

और हाँ, कोशिश … पकड़ कुछ उपयोगी नहीं है (कॉल स्टैक खोने के अलावा – तो यह वास्तव में बदतर है – जब तक कि किसी कारण से आप इस जानकारी का खुलासा नहीं करना चाहते हैं)।

एक बात जिसने लोगों का उल्लेख नहीं किया है, जबकि एनआईटी भाषाओं वास्तव में एक उचित अंतर नहीं बनाते हैं, एक अपवाद तब होता है जब कोई कार्रवाई की जानी चाहिए और चाहे वह इसका समाधान करेगा, वास्तव में अलग सवाल हैं। ऐसे कई मामले हैं जहां अपवादों के आधार पर कार्रवाई की जानी चाहिए, किसी को हल करने की कोई उम्मीद नहीं है, और कुछ मामलों में जहां अपवाद को "हल" करने के लिए जरूरी है, किसी निश्चित बिंदु के ढेर को खोलना है – आगे की कोई आवश्यकता नहीं है ।

सामान्य ज्ञान की वजह से एक को "पकड़" को "पकड़" करना चाहिए, कई कोड जो अपवाद होने पर कार्रवाई करना चाहिए, नहीं। उदाहरण के लिए, बहुत से कोड लॉक प्राप्त करेगा, एक अवस्था में "अस्थायी रूप से" पहचाने गए ऑब्जेक्ट को अपने अव्यवहारियों का उल्लंघन करता है, फिर उसे एक वैध स्थिति में डाल दिया जाता है, और फिर किसी और को ऑब्जेक्ट को देखे जाने से पहले लॉक को छोड़ दें। यदि कोई अपवाद तब होता है जब वस्तु खतरनाक-अमान्य राज्य में होती है, तो सामान्य प्रथा है कि ताला को उस स्थिति में अब भी वस्तु के साथ जारी किया जा सकता है। एक बेहतर पैटर्न के लिए अपवाद होता है, जब वस्तु "खतरनाक" स्थिति में होती है तो स्पष्ट रूप से लॉक को अमान्य कर दिया जाता है, इसलिए भविष्य में किसी भी प्रयास को तुरंत प्राप्त करने में विफल हो जाता है। ऐसे पैटर्न का लगातार उपयोग, तथाकथित "पॉकेमैन" अपवाद हैंडलिंग की सुरक्षा में काफी सुधार होगा, जो आईएमएचओ को मुख्यतः कोड के कारण खराब प्रतिष्ठा प्राप्त होती है, जो पहले उचित कार्रवाई किए बिना अपवाद उत्पन्न करने की अनुमति देता है

अधिकांश। NET भाषाओं में, एक अपवाद के आधार पर कार्रवाई करने के लिए कोड का एकमात्र तरीका है (भले ही यह जानता है कि यह अपवाद को हल करने वाला नहीं है), सवाल में कार्रवाई करने और उसके बाद पुनः throw )। एक अन्य संभावित दृष्टिकोण अगर कोड को कोई फर्क नहीं पड़ता है, इसके बारे में कोई परवाह नहीं है, तो try/finally ब्लॉक के साथ एक ok ध्वज का उपयोग करें; ब्लॉकों से पहले ok झंडे को सेट करें, और ब्लॉक के बाहर आने से पहले और ब्लॉक के भीतर return किसी भी return से पहले। फिर, finally , मान लें कि यदि ok से सेट नहीं किया गया है, तो अपवाद होना चाहिए। इस तरह के दृष्टिकोण को catch / throw से बेहतर ढंग से बेहतर है, लेकिन यह बदसूरत है और यह कम होना चाहिए जो कि होना चाहिए।

यह निर्भर करता है कि आप कैच ब्लॉक में क्या कर रहे हैं, और अगर आप त्रुटि को कॉलिंग कोड पर पास करना चाहते हैं या नहीं।

आप कह सकते हैं Catch io.FileNotFoundExeption ex और फिर एक वैकल्पिक फ़ाइल पथ या कुछ ऐसे का उपयोग करें, लेकिन फिर भी त्रुटि को फेंक दें

Throw Ex की बजाए Throw करने से आपको पूर्ण स्टैक ट्रेस रखने की सुविधा मिलती है। पूर्व फेंक दें थ्रो बयान से स्टैक ट्रेस को पुन: शुरु करें (मुझे आशा है कि यह समझ में आता है)।

उदाहरण के लिए, आपने जो पोस्ट में पोस्ट किया है, वास्तव में, अपवाद को पकड़ने में कोई मतलब नहीं है क्योंकि पकड़ पर कुछ भी नहीं किया जाता है, यह सिर्फ वही बहाया जाता है, वास्तव में यह अधिक से अधिक नुकसान होता है क्योंकि कॉल स्टैक खो जाता है ।

हालांकि, अपवाद की स्थिति में कुछ तर्क (उदाहरण के लिए, फ़ाइल लॉक के एसक्यूएल कनेक्शन बंद करने, या बस कुछ लॉगिंग) करने के लिए अपवाद को पकड़ना होगा, इसे निपटने के लिए कॉलिंग कोड पर इसे वापस फेंकना होगा। यह फ्रंट एंड कोड की तुलना में व्यावसायिक परत में अधिक सामान्य होगा क्योंकि आप अपवाद को संभालने के लिए कोडर को अपनी व्यावसायिक परत को लागू करना चाहेंगे।

फिर से पुनरावृत्त करने के लिए, हालांकि आपके द्वारा पोस्ट किए गए उदाहरण में अपवाद को पकड़ने में कोई मतलब नहीं है। ऐसा मत करो!

पकड़ने का एक संभावित कारण किसी भी अपवाद फ़िल्टर को नीचे फ़िल्टरिंग ( यादृच्छिक पुराने लिंक ) से गहराई से स्टैक को निष्क्रिय करना है। लेकिन जाहिर है, अगर यह इरादा था, तो ऐसा कहने पर एक टिप्पणी होगी।

क्षमा करें, लेकिन "बेहतर डिज़ाइन" के रूप में कई उदाहरण अभी भी बुरी तरह गंध करते हैं या बेहद भ्रामक हो सकते हैं। {} पकड़ {लॉग; फेंक दो) बस बिल्कुल व्यर्थ है अपवाद प्रवेश आवेदन के अंदर केंद्रीय स्थान पर किया जाना चाहिए। किसी भी तरह स्टैकट्र्रेस को बुलबुला अपवाद देता है, क्यों नहीं उन्हें सिस्टम की सीमाओं के ऊपर कहीं और लॉग इन करें?

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

अन्य लोगों ने क्या कहा है इसके अलावा, एक संबंधित प्रश्न का उत्तर देखें जो दर्शाता है कि पकड़ने और पुनर्स्थापन एक नो-ऑप नहीं है (यह वीबी में है, लेकिन कुछ कोड VB से सी # को लागू किए जा सकते हैं)

परिदृश्य के बारे में बात करने के अधिकांश जवाब पकड़-लॉग-रिओरो

इसे अपने कोड में लिखने के बजाय एओपी का उपयोग करने पर विचार करें, विशेष रूप से पोस्टशारप। डायग्नोस्टिक। टॉलिककिट ऑन एक्सेसिवेशन ऑप्शन के साथ इसमें शामिल करेंपीरामेटर वेल्यू और इसमें शामिल करेंअगर

जबकि अन्य जवाबों में से बहुत से अच्छे उदाहरण दिए गए हैं, इसलिए आप एक अपवाद को एक अपवाद क्यों पकड़ना चाहते हैं, किसी ने भी 'आखिरकार' परिदृश्य का उल्लेख नहीं किया है

इस का एक उदाहरण है जहां आपके पास एक ऐसा तरीका है जिसमें आप कर्सर सेट करते हैं (उदाहरण के लिए एक प्रतीक्षा कर्सर), विधि में कई निकास बिंदु हैं (उदाहरण के लिए यदि ()); और आप यह सुनिश्चित करना चाहते हैं कि कर्सर रीसेट हो विधि का अंत

ऐसा करने के लिए आप सभी कोड को एक प्रयास / पकड़ / अंत में लपेट कर सकते हैं। अंत में कर्सर को सही कर्सर को वापस सेट करें ताकि आप किसी भी वैध अपवाद को दफन नहीं करें, इसे पकड़ने में पुनर्स्थापित करें।

 try { Cursor.Current = Cursors.WaitCursor; // Test something if (testResult) return; // Do something else } catch { throw; } finally { Cursor.Current = Cursors.Default; }