2009-04-26 16 views
40

सी # का उपयोग करना, बदसूरत पकड़ ब्लॉक के गुच्छा के बजाय कई प्रकार के अपवादों को संभालने का एक बेहतर तरीका है?एकाधिक कैच ब्लॉक से अधिक सुरुचिपूर्ण अपवाद हैंडलिंग?

इस प्रकार की स्थिति के लिए सबसे अच्छा अभ्यास क्या माना जाता है?

उदाहरण के लिए:

try 
{ 
    // Many types of exceptions can be thrown 
} 
catch (CustomException ce) 
{ 
    ... 
} 
catch (AnotherCustomException ace) 
{ 
    ... 
} 
catch (Exception ex) 
{ 
    ... 
} 

उत्तर

68

मेरी राय में, "बदसूरत" पकड़ ब्लॉक के एक गुच्छा का सबसे अच्छा तरीका है कि स्थिति से निपटने के लिए है।

कारण मुझे यह पसंद है कि यह बहुत स्पष्ट है। आप स्पष्ट रूप से बता रहे हैं कि आप कौन से अपवादों को संभालना चाहते हैं, और उन्हें कैसे संभाला जाना चाहिए। अधिक संक्षिप्त रूपों में हैंडलिंग करने की कोशिश करने के अन्य रूप अधिकांश मामलों में पठनीयता खो देते हैं।

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

+0

क्या आप मार्क ब्रैकेट के फ़िल्टर समाधान के लिए कोई डाउनसाइड्स देखते हैं? – TrueWill

+0

@ ट्राउविल: आईएमओ, यह वास्तव में बहुत सारी कार्यक्षमता को जोड़ने के बिना, रखरखाव को कम करता है। कहा जा रहा है, यह भयानक नहीं है - बस स्पष्ट नहीं है। –

10
दुर्भाग्य

, C# does not have user exception filters VB.NET की तरह है, तो आप करने के लिए सीमित कर रहे हैं: सभी अपवादों को करने के लिए एक आम पूर्वज पकड़ने

  1. । यह आप जो चाहते हैं वह हो सकता है या नहीं भी हो सकता है, क्योंकि अन्य वंशज अपवाद प्रकार हो सकते हैं जिन्हें आप पकड़ना नहीं चाहते हैं।
  2. अपवाद हैंडलिंग तर्क को किसी अन्य विधि में स्थानांतरित करना और प्रत्येक हैंडलर से कॉल करना।
  3. प्रत्येक हैंडलर के लिए अपवाद तर्क दोहराएं।
  4. अपवाद हैंडलिंग तर्क को ऐसी भाषा में स्थानांतरित करना जो फ़िल्टर का समर्थन करता है, जैसे VB.NET।
+5

सी # 6.0 भाषा विनिर्देश (.NET 4.6/विजुअल स्टूडियो 2015 में नया) के रूप में, सी # वाक्यविन्यास का उपयोग करके "अपवाद फ़िल्टर" का समर्थन करता है: 'पकड़ (अपवाद पूर्व) अगर (उदा। संदेश। ("घातक")) ' । – qJake

21

मैं रीड से सहमत हूं: यह सबसे अच्छा तरीका है।

मैं इन टिप्पणियों जोड़ना होगा:

केवल कुछ आप के बारे में कुछ करने के लिए जा रहे हैं पकड़ने। यदि आप समस्या को ठीक नहीं कर सकते हैं, तो एक विशिष्ट अपवाद को पकड़ने में कोई बात नहीं है।

कैच ब्लॉक का अधिक उपयोग न करें। कई मामलों में जहां आप अपवाद को हल नहीं कर सकते हैं, बस अपवाद बबल को केंद्रीय बिंदु (जैसे पेज_इरर) तक छोड़ना और उसे वहां पकड़ना सबसे अच्छा है। फिर, आप अपवाद लॉग करते हैं और उपयोगकर्ता को एक संदेश प्रदर्शित करते हैं।

+6

+1 - "अतिरिक्त" अपवादों को पकड़ने के बारे में महान बिंदु। मैं यह उल्लेख करने की कोशिश कर रहा था कि (मेरी कहानियों में यह आपको स्पष्ट करता है कि आप जो संभालना चाहते हैं उसके बारे में स्पष्ट होना) - लेकिन आप सही हैं - आपको आमतौर पर सब कुछ संभाल नहीं लेना चाहिए, जब तक कि आप इसे सार्थक में संभालने वाले नहीं होते मार्ग। –

+1

भी +1। मैं यह जोड़ना चाहता हूं कि कभी-कभी डेवलपर प्रत्येक विधि में कैच ब्लॉक जोड़ते हैं ताकि वे पता लगा सकें कि वास्तव में किस विधि ने अपवाद फेंक दिया है। स्टैक ट्रेस के लिए यही है! –

-6

पकड़ने केवल क्या आप विशेष रूप से हल करने के लिए और छोड़

catch(Exception e) 
{ 
} 
सब कुछ के लिए

(या इसे छोड़ सकते हैं और ढेर को यह अपवाद दे)

+6

क्या यह अपवाद को पूरी तरह से निगल नहीं देगा, जो लगभग हमेशा एक बुरा विचार है? – Ben

+4

हां, यह कोड का एक अद्भुत टुकड़ा है, जैसा है। मुझे लगता है कि मैश का मतलब था कि आप वहां फेंकते हैं ... या तो वह या वह नशे में था। – Maverick

1

आप उद्यम लाइब्रेरी Exception Handling block की जांच करनी चाहिए की जरूरत है। यह नीतियों (रैपिंग नीतियों, प्रचार नीतियों, प्रतिस्थापन नीतियों, लॉगिंग नीतियों इत्यादि) के माध्यम से अपवादों पर अधिक बढ़िया अनाज नियंत्रण की अनुमति देता है। आप इसे अपवाद ब्लॉक कोड करने के तरीके का मानकीकरण करने के लिए उपयोग कर सकते हैं और कॉन्फ़िगरेशन का उपयोग ठीक से संभालने के लिए कर सकते हैं एक विशेष प्रकार का अपवाद।

15

केवल दूसरी बात आप का अनुकरण है VB.NET के अपवाद फिल्टर कर सकते हैं के बारे में:

try { 
    DoSomething(); 
} catch (Exception e) { 
    if (!ex is CustomException && !ex is AnotherCustomException) { 
     throw; 
    } 
    // handle 
} 

कभी कभी यह बेहतर है, कभी कभी नहीं।यदि मैं हैंडलर में कुछ सामान्य तर्क चाहता था, तो मैं मुख्य रूप से इसका उपयोग करता हूं, लेकिन अपवाद आधार प्रकार साझा नहीं करते हैं।

+2

नकारात्मक तर्क मेरी बाएं आंख को हास्यास्पद लग रहा है। इस तरह के मामले में, कैसे 'अगर (! (पूर्व कस्टमएक्सप्शन || पूर्व है दूसरा कस्टम अपवाद))'? – Craig

+3

यह अभी भी नकारात्मक तर्क है, आप बस उस पर डी मॉर्गन भाग गए। पठनीयता किसी भी तरह से खराब तरीके से खराब है। मैं कुछ ऐसा करूंगा जैसे 'अगर (कस्टम कस्टम एक्सेप्शन || एक्स एक और कस्टम एक्सेप्शन है) {/ * हैंडल * /} else {throw; } 'या 'बूल कैनहेन्डल = एक्स कस्टम अपवाद || है पूर्व एक और कस्टम अपवाद है; अगर (! canHandle) फेंक;/* हैंडल */' – Timbo

0

क्या यह तरीका अच्छा नहीं है?

आप केवल एक अपवाद को संभालने के लिए चाहते हैं:

try 
{ 
    // Many types of exceptions can be thrown 
} 
catch (TheExceptionIWantToHandle ex) 
{ 
    // handle it 
} 
catch (Exception ex) 
{ 
    // suppress all other exceptions 
} 

आप एक को छोड़कर सभी अपवादों को संभालने के लिए चाहते हैं:

try 
{ 
    // Many types of exceptions can be thrown 
} 
catch (TheExceptionIDoNotWantToHandle ex) 
{ 
    // suppress all other exceptions 
} 
catch (Exception ex) 
{ 
    // handle it 
} 

अच्छा, अच्छा नहीं?

+3

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

5

यदि आपको इस तरह के कोड की वास्तव में बड़ी राशि लिखनी है तो मैं कुछ AOP ढांचे की जांच करने का सुझाव दूंगा। मैं व्यक्तिगत रूप से PostSharp का उपयोग करता हूं। फिर आप सभी अपवाद हैंडलिंग कोड को पहलुओं में छुपा सकते हैं।

संबंधित मुद्दे