एक बार में कई अपवाद पकड़ो?


2140

यह बस पकड़ने के लिए हतोत्साहित किया जाता है System.Exception। इसके बजाय, केवल "ज्ञात" अपवादों को पकड़ा जाना चाहिए।

अब, यह कभी-कभी अस्वाभाविक दोहराव कोड की ओर जाता है, उदाहरण के लिए:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
    WebId = Guid.Empty;
}
catch (OverflowException)
{
    WebId = Guid.Empty;
}

मुझे आश्चर्य है: क्या दोनों अपवादों को पकड़ने का एक तरीका है और केवल कॉल करना है WebId = Guid.Empty एक बार कॉल करना है?

दिए गए उदाहरण बल्कि सरल है, क्योंकि यह केवल एक है GUID। लेकिन उस कोड की कल्पना करें जहां आप कई बार किसी ऑब्जेक्ट को संशोधित करते हैं, और यदि कोई हेरफेर अपेक्षित तरीके से विफल हो जाता है, तो आप "रीसेट" करना चाहते हैं object। हालांकि, अगर कोई अप्रत्याशित अपवाद है, तो मैं अभी भी उस उच्च को फेंकना चाहता हूं।


5
यदि आप .net 4 और इसके बाद के संस्करण का उपयोग कर रहे हैं, तो मैं कुल मिलाकर का उपयोग करना पसंद करता हूं msdn.microsoft.com/en-us/library/system.aggregateexception.aspx
Bepenfriends

2
Bepenfriends- के बाद से System.Guid फेंक नहीं है AggregateException , यदि आप (या कोई) दिखा कैसे आप एक AggregateException आदि .. में लपेट होगा एक जवाब पोस्ट कर सकता बहुत अच्छा होगा
बांध


11
"यह केवल System.Exception को पकड़ने के लिए हतोत्साहित किया जाता है।" -और अगर विधि 32 प्रकार के अपवादों को फेंक सकती है, तो कोई क्या करता है? उनमें से प्रत्येक के लिए अलग से कैच लिखें?
जियोर्जिम

5
यदि कोई विधि 32 अलग-अलग प्रकार के अपवादों को फेंकती है, तो यह बुरी तरह से लिखा गया है। यह या तो अपवादों को नहीं पकड़ रहा है जो स्वयं कॉल कर रहे हैं, यह एक विधि में बहुत अधिक एफएआर कर रहा है, या उन 32 के बहुमत / सभी को एक कारण कोड के साथ एक एकल अपवाद होना चाहिए।
19n17

जवाबों:


2100

System.Exceptionप्रकारों पर पकड़ और स्विच करें

catch (Exception ex)            
{                
    if (ex is FormatException || ex is OverflowException)
    {
        WebId = Guid.Empty;
        return;
    }

    throw;
}

69
दुर्भाग्य से, FxCop (यानी - विजुअल स्टूडियो कोड विश्लेषण) यह पसंद नहीं है जब आप अपवाद को पकड़ते हैं।
एंड्रयू गैरीसन

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

28
FxCop का नवीनतम संस्करण एक अपवाद नहीं फेंकता है जब ऊपर दिए गए कोड का उपयोग किया जाता है।
पीटर

28
यह सुनिश्चित नहीं है कि पहली बार में ओपी कोड में क्या गलत था। # 1 स्वीकृत उत्तर लगभग दो बार कई पंक्तियों का है और बहुत कम पठनीय है।
जोआ ब्रगनका

22
@ JoãoBragança: जबकि इस उदाहरण में यह उत्तर अधिक पंक्तियों का उपयोग करता है, तो कल्पना करने की कोशिश करें कि क्या आप उदाहरण के लिए फ़ाइल IO के साथ काम कर रहे हैं, और आप जो करना चाहते हैं, वे उन अपवादों को पकड़ सकते हैं और कुछ लॉग मैसेजिंग कर सकते हैं, लेकिन केवल वे ही आप पर आने की उम्मीद करते हैं फ़ाइल IO विधियाँ। फिर आपको अक्सर बड़ी संख्या (लगभग 5 या अधिक) विभिन्न प्रकार के अपवादों से निपटना पड़ता है। उस स्थिति में, यह दृष्टिकोण आपको कुछ लाइनें बचा सकता है।
Xilconic

594

संपादित करें: मैं दूसरों के साथ, जो कह रहा हूं कि C # 6.0 के रूप में, अपवाद फ़िल्टर अब जाने के लिए एक बिल्कुल ठीक तरीका है:catch (Exception ex) when (ex is ... || ex is ... )

सिवाय इसके कि मैं अभी भी एक-लाइन लाइन से नफरत करता हूं और निम्नलिखित की तरह व्यक्तिगत रूप से कोड को बाहर करूंगा। मुझे लगता है कि यह उतना ही कार्यात्मक है जितना कि यह सौंदर्यवादी है, क्योंकि मेरा मानना ​​है कि यह समझ में सुधार करता है। कुछ असहमत हो सकते हैं:

catch (Exception ex) when (
    ex is ...
    || ex is ...
    || ex is ...
)

मूल:

मुझे पता है कि मुझे यहां पार्टी में थोड़ी देर हो गई है, लेकिन पवित्र धुआं ...

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

private void TestMethod ()
{
    Action<Exception> errorHandler = ( ex ) => {
        // write to a log, whatever...
    };

    try
    {
        // try some stuff
    }
    catch ( FormatException  ex ) { errorHandler ( ex ); }
    catch ( OverflowException ex ) { errorHandler ( ex ); }
    catch ( ArgumentNullException ex ) { errorHandler ( ex ); }
}

मैं मदद नहीं कर सकता, लेकिन आश्चर्य ( चेतावनी: थोड़ा विडंबना / व्यंग्य आगे) क्यों पृथ्वी पर मूल रूप से सिर्फ निम्नलिखित को बदलने के लिए यह सभी प्रयास किए जाते हैं:

try
{
    // try some stuff
}
catch( FormatException ex ){}
catch( OverflowException ex ){}
catch( ArgumentNullException ex ){}

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

// sorta sucks, let's be honest...
try
{
    // try some stuff
}
catch( Exception ex )
{
    if (ex is FormatException ||
        ex is OverflowException ||
        ex is ArgumentNullException)
    {
        // write to a log, whatever...
        return;
    }
    throw;
}

क्योंकि यह निश्चित रूप से स्वचालित रूप से अधिक पठनीय नहीं है।

दी, मैंने /* write to a log, whatever... */ return;पहले उदाहरण में से तीन समान उदाहरणों को छोड़ दिया ।

लेकिन यह मेरी बात है। Y'all कार्यों / विधियों के बारे में सुना है, है ना? गंभीरता से। एक सामान्य ErrorHandlerफ़ंक्शन लिखें और, प्रत्येक कैच ब्लॉक से इसे कॉल करें।

यदि आप मुझसे पूछते हैं, तो दूसरा उदाहरण ( ifऔर isखोजशब्दों के साथ) दोनों काफी कम पठनीय है, और साथ ही साथ आपकी परियोजना के रखरखाव चरण के दौरान काफी अधिक त्रुटि-प्रवण है।

रखरखाव चरण, जो किसी के लिए प्रोग्रामिंग के लिए अपेक्षाकृत नया हो सकता है, में आपकी परियोजना के संपूर्ण जीवनकाल का 98.7% या अधिक शामिल है, और रखरखाव करने वाले घटिया schmuck लगभग निश्चित रूप से आपके अलावा कोई और होने जा रहा है। और एक बहुत अच्छा मौका है कि वे अपना 50% समय आपके नाम को कोसते हुए काम पर लगाएंगे।

और निश्चित रूप से आप पर FxCop छाल करता है और इसलिए आपको अपने कोड में एक विशेषता भी जोड़ना होगा जो चल रहे कार्यक्रम के साथ ठीक करने के लिए ज़िप है, और केवल एक समस्या को अनदेखा करने के लिए FxCop को बताना है कि 99.9% मामलों में यह पूरी तरह से है झंडी दिखाने में सही। और, क्षमा करें, मुझसे गलती हो सकती है, लेकिन क्या वास्तव में आपके ऐप में संकलित "अनदेखी" विशेषता समाप्त नहीं होती है?

क्या पूरी ifपरीक्षा को एक पंक्ति में रखना इसे और अधिक पठनीय बना देगा? मुझे ऐसा नहीं लगता। मेरा मतलब है, मेरे पास एक और प्रोग्रामर था जो बहुत पहले एक बार बहस कर चुका था कि एक लाइन पर अधिक कोड डालने से यह "और तेज" होगा। लेकिन निश्चित रूप से वह पागल पागल था। उसे समझाने की कोशिश करते हुए (एक सीधे चेहरे के साथ - जो चुनौतीपूर्ण था) कि दुभाषिया या संकलक एक-निर्देश-निर्देश-प्रति-पंक्ति कथनों को अलग करने वाली उस लंबी रेखा को कैसे तोड़ देगा - अनिवार्य रूप से परिणाम के समान है यदि वह आगे बढ़ गया था और संकलक को आउट-चालाक करने की कोशिश के बजाय कोड को केवल पठनीय बनाया गया - जिसका उस पर कोई प्रभाव नहीं पड़ा। लेकिन मैं पीछे हटा।

जब आप तीन और अपवाद प्रकार, एक या दो महीने जोड़ते हैं, तो यह कितना कम पठनीय होता है? (उत्तर: यह बहुत कम पठनीय होता है)।

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

बस केह रहा हू...

// super sucks...
catch( Exception ex )
{
    if ( ex is FormatException || ex is OverflowException || ex is ArgumentNullException )
    {
        // write to a log, whatever...
        return;
    }
    throw;
}

36
जब मैं पहली बार इस प्रश्न से टकराया था तो मैं स्वीकृत उत्तर पर था। कूल I बस सभी Exceptions को पकड़ सकता है और प्रकार की जांच कर सकता है। मुझे लगा कि इसने कोड को साफ कर दिया है, लेकिन कुछ ने मुझे प्रश्न पर वापस आने के लिए रखा और मैंने वास्तव में प्रश्न के अन्य उत्तरों को पढ़ा। मैं थोड़ी देर के लिए उस पर चबा गया, लेकिन मुझे आपके साथ सहमत होना होगा। अपने कोड को सूखने के लिए फ़ंक्शन का उपयोग करने से अधिक पठनीय और बनाए रखने योग्य है, सब कुछ पकड़ने के लिए, किसी सूची के खिलाफ तुलना करने वाले प्रकार की जांच करना, कोड लपेटना और फेंकना। देर से आने और एक वैकल्पिक और समझदार (IMO) विकल्प प्रदान करने के लिए धन्यवाद। +1।
एरियल

8
यदि आप शामिल करना चाहते हैं, तो एक त्रुटि हैंडलिंग फ़ंक्शन का उपयोग करना काम नहीं करेगा throw;। आपको प्रत्येक कैच ब्लॉक में कोड की उस पंक्ति को दोहराना होगा (जाहिर है कि दुनिया का अंत नहीं है, लेकिन यह उल्लेख के लायक है क्योंकि यह कोड है जिसे दोहराया जाना चाहिए)।
kad81

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

2
हाय @Ritffunk, बस के Func<Exception, MyEnumType>बजाय का उपयोग करें Action<Exception>। यही कारण है कि केFunc<T, Result> , Resultवापसी प्रकार होने के साथ ।
क्रेग

3
मैं यहाँ पूरी तरह से समझौते में हूँ। मैंने भी पहला उत्तर पढ़ा और सोचा कि यह तर्कसंगत है। सभी अपवाद हैंडलर के लिए एक सामान्य 1 में ले जाया गया। मेरे अंदर के कुछ ने मुझे आंतरिक रूप से puke बना दिया ... इसलिए मैंने कोड को वापस कर दिया। फिर इस सुंदरता में आया! इसके लिए स्वीकृत उत्तर होना जरूरी है
कॉनर गलाघर

372

जैसा कि अन्य लोगों ने बताया है, ifआपके कैच ब्लॉक के अंदर एक स्टेटमेंट हो सकता है ताकि यह पता चल सके कि क्या चल रहा है। C # 6 अपवाद फ़िल्टर का समर्थन करता है, इसलिए निम्नलिखित कार्य करेगा:

try {  }
catch (Exception e) when (MyFilter(e))
{
    
}

MyFilterविधि तो कुछ इस तरह दिखाई दे सकता है:

private bool MyFilter(Exception e)
{
  return e is ArgumentNullException || e is FormatException;
}

वैकल्पिक रूप से, यह सब इनलाइन किया जा सकता है (जब स्टेटमेंट के दाहिने हाथ की तरफ सिर्फ बूलियन एक्सप्रेशन होना चाहिए)।

try {  }
catch (Exception e) when (e is ArgumentNullException || e is FormatException)
{
    
}

यह ब्लॉक के ifभीतर से एक बयान का उपयोग करने से अलग है catch, अपवाद फ़िल्टर का उपयोग करके स्टैक को खोलना नहीं होगा

इसे देखने के लिए आप Visual Studio 2015 डाउनलोड कर सकते हैं।

यदि आप Visual Studio 2013 का उपयोग जारी रखना चाहते हैं, तो आप निम्नलिखित नगेट पैकेज स्थापित कर सकते हैं:

Microsoft.Net.Compilers स्थापित करें

लेखन के समय, इसमें C # 6 का समर्थन शामिल होगा।

इस पैकेज को संदर्भित करने से किसी भी सिस्टम इंस्टॉल किए गए संस्करण के विपरीत परियोजना के पैकेज में शामिल C # और विज़ुअल बेसिक कंपाइलरों के विशिष्ट संस्करण का उपयोग करके प्रोजेक्ट बनाया जाएगा।


3
धैर्यपूर्वक 6 की आधिकारिक रिलीज की प्रतीक्षा कर रहा हूं ... मैं यह देखना चाहता हूं कि ऐसा होने पर चेक प्राप्त करें।
रबरडुक

@ रबरडक मैं C # से अशक्त प्रसार संचालक के लिए मर रहा हूं। मेरी बाकी टीम को समझाने की कोशिश कर रहा है कि एक अस्थिर भाषा / संकलक का जोखिम इसके लायक है। भारी प्रभाव के साथ मामूली सुधार। उत्तर के रूप में चिह्नित होने के लिए, महत्वपूर्ण नहीं है, जब तक कि लोगों को यह पता चलता है कि यह संभव है / है, मुझे खुशी है।
जो

सही?! मैं निकट भविष्य में अपने कोड आधार पर एक अच्छी नज़र रखूंगा। =) मुझे पता है कि चेक महत्वपूर्ण नहीं है, लेकिन दिया गया जवाब जल्द ही पुराना हो जाएगा, मैं उम्मीद कर रहा हूं कि ओपी इसे चेक करने के लिए वापस आएगा ताकि इसे उचित दृश्यता मिल सके।
रबरडैक

आंशिक रूप से यही कारण है कि मैंने इसे अभी तक @Joe से सम्मानित नहीं किया है। मैं चाहता हूं कि यह दिखाई दे। यद्यपि आप स्पष्टता के लिए इनलाइन फ़िल्टर का एक उदाहरण जोड़ना चाह सकते हैं।
रबरडैक

188

C # दुर्भाग्य से नहीं, क्योंकि आपको इसे करने के लिए एक अपवाद फ़िल्टर की आवश्यकता होगी और C # MSIL की उस विशेषता को उजागर नहीं करता है। VB.NET में यह क्षमता है, उदाहरण के लिए

Catch ex As Exception When TypeOf ex Is FormatException OrElse TypeOf ex Is OverflowException

अपने ऑन-एरर कोड को एनकोड करने के लिए आप क्या कर सकते हैं एक अनाम फ़ंक्शन का उपयोग करें, और फिर इसे उन विशिष्ट कैच ब्लॉक्स में कॉल करें:

Action onError = () => WebId = Guid.Empty;
try
{
    // something
}
catch (FormatException)
{
    onError();
}
catch (OverflowException)
{
    onError();
}

26
दिलचस्प विचार है और एक और उदाहरण VB.net से अधिक सी # कुछ दिलचस्प फायदे कभी कभी यह है कि
माइकल Stum

47
@MichaelStum उस तरह के सिंटैक्स के साथ मैं शायद ही इसे दिलचस्प
कहूंगा

17
अपवाद फ़िल्टर c # 6 में आ रहे हैं! Roslyn.codeplex.com/discussions/541301 को पुनर्विचार करने के
Arne Deruwe

@ArneDeruwe उस लिंक के लिए धन्यवाद! मैंने सिर्फ एक और महत्वपूर्ण कारण सीखा है पुन: फेंकने के लिए नहीं: throw e;स्टैकट्रेस और कॉलस्टैक को throw;नष्ट कर देता है , "केवल" कॉलस्टैक (क्रैश-डंप बेकार प्रदान करता है!) को नष्ट कर देता है न ही उपयोग करने का एक बहुत अच्छा कारण अगर इसे टाला जा सकता है!
14

1
C # 6 अपवाद फ़िल्टर उपलब्ध हैं! आखिरकार।
डैनी

134

पूर्णता के लिए, .NET 4.0 के बाद से कोड को फिर से लिखा जा सकता है:

Guid.TryParse(queryString["web"], out WebId);

TryParse कभी भी अपवादों को नहीं फेंकता है और अगर गलत है, तो WebId को सेट करना गलत है Guid.Empty


C # 7 के बाद से आप एक अलग लाइन पर एक वैरिएबल शुरू करने से बच सकते हैं:

Guid.TryParse(queryString["web"], out Guid webId);

आप रिटर्निंग टुपल्स को पार्स करने की विधियाँ भी बना सकते हैं, जो .NET फ्रेमवर्क में अभी तक संस्करण 4.6 में उपलब्ध नहीं हैं:

(bool success, Guid result) TryParseGuid(string input) =>
    (Guid.TryParse(input, out Guid result), result);

और उन्हें इस तरह से उपयोग करें:

WebId = TryParseGuid(queryString["web"]).result;
// or
var tuple = TryParseGuid(queryString["web"]);
WebId = tuple.success ? tuple.result : DefaultWebId;

इस बेकार उत्तर के लिए अगला अनुपयोगी अपडेट तब आता है जब आउट-मापदंडों का डिक्रिप्शन C # 12. में लागू किया जाता है :)


19
संक्षेप में - संक्षिप्त, और आप पूरी तरह से अपवाद से निपटने के प्रदर्शन के दंड को दरकिनार कर देते हैं, जानबूझकर प्रोग्राम प्रवाह को नियंत्रित करने के लिए अपवादों का उपयोग करने का बुरा रूप, और आपके रूपांतरण तर्क के चारों ओर फैलने का नरम फोकस, यहां थोड़ा सा और थोड़ा सा है ।
क्रेग

9
मुझे पता है कि आपका क्या मतलब था, लेकिन निश्चित रूप से Guid.TryParseकभी नहीं लौटता Guid.Empty। यदि स्ट्रिंग गलत प्रारूप में है, तो यह resultआउटपुट पैरामीटर को सेट करता है Guid.Empty, लेकिन यह वापस आ जाता है false । मैं इसका उल्लेख कर रहा हूं क्योंकि मैंने कोड देखा है जो शैली में चीजें करता है Guid.TryParse(s, out guid); if (guid == Guid.Empty) { /* handle invalid s */ }, जो आमतौर पर गलत होता है यदि sस्ट्रिंग का प्रतिनिधित्व हो सकता है Guid.Empty

14
वाह आपने प्रश्न का उत्तर दिया है, सिवाय इसके कि यह प्रश्न की भावना में नहीं है। बड़ी समस्या कुछ और है :(
nawfal

6
ट्राइसेपर्स का उपयोग करने के लिए उचित पैटर्न, निश्चित रूप से अधिक पसंद है if( Guid.TryParse(s, out guid){ /* success! */ } else { /* handle invalid s */ }, जो टूटे उदाहरण की तरह कोई अस्पष्टता नहीं छोड़ता है जहां इनपुट मूल्य वास्तव में एक गाइड का स्ट्रिंग प्रतिनिधित्व हो सकता है।
क्रेग

2
यह उत्तर वास्तव में Guid.Parse के संबंध में सही हो सकता है, लेकिन यह मूल प्रश्न के पूरे बिंदु से चूक गया है। जिसका Guide.Parse से कोई लेना-देना नहीं था, लेकिन अपवाद बनाम FormatException / OverflowException / etc को पकड़ने के संबंध में था।
कोनोर गलघेर

114

अपवाद फ़िल्टर अब c # 6+ में उपलब्ध हैं। तुम कर सकते हो

try
{
       WebId = new Guid(queryString["web"]);
}
catch (Exception ex) when(ex is FormatException || ex is OverflowException)
{
     WebId = Guid.Empty;
}

C # 7.0+ में, आप इसे पैटर्न मिलान के साथ भी जोड़ सकते हैं

try
{
   await Task.WaitAll(tasks);
}
catch (Exception ex) when( ex is AggregateException ae &&
                           ae.InnerExceptions.Count > tasks.Count/2)
{
   //More than half of the tasks failed maybe..? 
}

इस पद्धति को न केवल इसलिए पसंद किया जाता है क्योंकि यह सरल और स्पष्ट है, बल्कि शर्तों को पूरा नहीं करने पर स्टैक को खोलना भी नहीं पड़ता है, जो कि रीहैरो के साथ तुलना में बेहतर प्रदर्शन और नैदानिक ​​जानकारी प्रदान करता है।
जो

74

यदि आप अपने एप्लिकेशन को C # 6 में अपग्रेड कर सकते हैं तो आप भाग्यशाली हैं। नए C # संस्करण में अपवाद फ़िल्टर लागू किया गया है। तो आप इसे लिख सकते हैं:

catch (Exception ex) when (ex is FormatException || ex is OverflowException) {
    WebId = Guid.Empty;
}

कुछ लोगों को लगता है कि यह कोड वैसा ही है

catch (Exception ex) {                
    if (ex is FormatException || ex is OverflowException) {
        WebId = Guid.Empty;
    }
    throw;
}

लेकिन ऐसा नहीं है। वास्तव में यह C # 6 में एकमात्र नई विशेषता है जो पूर्व संस्करणों में अनुकरण करना संभव नहीं है। पहले, री-थ्रो का मतलब कैच लपकने से ज्यादा ओवरहेड होता है। दूसरा, यह शब्दार्थ के समकक्ष नहीं है। जब आप अपना कोड डीबग कर रहे होते हैं तो नई सुविधा स्टैक बरकरार रहती है। इस सुविधा के बिना क्रैश डंप कम उपयोगी है या बेकार भी है।

CodePlex पर इस बारे में एक चर्चा देखें । और अंतर दिखाने वाला एक उदाहरण


4
बिना किसी अपवाद के स्टैक को संरक्षित करता है, लेकिन "थ्रो एक्स" इसे अधिलेखित कर देगा।
इवान

32

आप एक का उपयोग नहीं करना चाहते हैं, तो ifभीतर बयान catchस्कोप, में C# 6.0आप उपयोग कर सकते Exception Filtersवाक्य रचना जो पहले से ही पूर्वावलोकन संस्करणों में CLR द्वारा समर्थित किया गया है, लेकिन केवल में ही अस्तित्व में VB.NET/ MSIL:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (Exception exception) when (exception is FormatException || ex is OverflowException)
{
    WebId = Guid.Empty;
}

यह कोड तभी पकड़ेगा Exceptionजब यह InvalidDataExceptionयाArgumentNullException

वास्तव में, आप मूल रूप से उस whenखंड के अंदर कोई भी शर्त रख सकते हैं :

static int a = 8;

...

catch (Exception exception) when (exception is InvalidDataException && a == 8)
{
    Console.WriteLine("Catch");
}

ध्यान दें कि 's' स्कोप के ifअंदर एक स्टेटमेंट के विपरीत catch, Exception Filtersफेंक नहीं सकते Exceptions, और जब वे करते हैं, या जब स्थिति नहीं होती है true, तो catchइसके बजाय अगली स्थिति का मूल्यांकन किया जाएगा:

static int a = 7;

static int b = 0;

...

try
{
    throw new InvalidDataException();
}
catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
{
    Console.WriteLine("Catch");
}
catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
{
    Console.WriteLine("General catch");
}

आउटपुट: सामान्य पकड़।

जब अधिक हो तो एक true Exception Filter- पहला स्वीकार किया जाएगा:

static int a = 8;

static int b = 4;

...

try
{
    throw new InvalidDataException();
}
catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
{
    Console.WriteLine("Catch");
}
catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
{
    Console.WriteLine("General catch");
}

आउटपुट: कैच।

और जैसा कि आप में देख सकते हैं MSILकोड को अनुवाद किया है नहीं ifबयान है, लेकिन करने के लिए Filters, और Exceptionsक्षेत्रों के साथ चिह्नित भीतर से फेंक नहीं किया जा सकता Filter 1और Filter 2लेकिन फिल्टर फेंकने Exceptionके बजाय असफल हो जायेगी, यह भी पिछले तुलना मूल्य से पहले ढेर करने के लिए धक्का दिया endfilterआदेश फ़िल्टर की सफलता / विफलता का निर्धारण करेगा ( Catch 1 XOR Catch 2 उसी के अनुसार निष्पादित करेगा):

अपवाद फ़िल्टर MSIL

इसके अलावा, विशेष Guidरूप से Guid.TryParseविधि है।


+1 जब फ़िल्टर और एकाधिक फ़िल्टर का उपयोग करने पर क्या होता है, इसका स्पष्टीकरण प्रदान करने के लिए +1।
स्टीवन87वेट

26

C # 7 के साथ माइकल स्टम का उत्तर स्विच स्टेटमेंट की पठनीयता को बनाए रखते हुए बेहतर बनाया जा सकता है:

catch (Exception ex)
{
    switch (ex)
    {
        case FormatException _:
        case OverflowException _:
            WebId = Guid.Empty;
            break;
        default:
            throw;
    }
}

और स्विच अभिव्यक्ति के रूप में C # 8 के साथ:

catch (Exception ex)
{
    WebId = ex switch
    {
        _ when ex is FormatException || ex is OverflowException => Guid.Empty,
        _ => throw ex
    };
}

3
यह 2018 IMHO के रूप में स्वीकृत उत्तर होना चाहिए।
मेम्फिज

6
Mat J का उत्तर प्रयोग whenस्विच की तुलना में कहीं अधिक सुरुचिपूर्ण / उपयुक्त है।
rgoliveira 15

@rgoliveira: मैं सहमत हूं कि प्रश्न में पूछे गए मामले के लिए, मैट जे द्वारा उत्तर अधिक सुरुचिपूर्ण और उपयुक्त है। हालांकि, यह पढ़ना मुश्किल हो जाता है कि क्या आपके पास अलग-अलग कोड है जिसे आप अपवाद प्रकार के आधार पर निष्पादित करना चाहते हैं या यदि आप वास्तव में अपवाद के उदाहरण का उपयोग करना चाहते हैं। इन सभी परिदृश्यों को इस स्विच स्टेटमेंट के साथ समान रूप से व्यवहार किया जा सकता है।
फैबियन

1
@ फैबियन "यदि आपके पास अलग कोड है जिसे आप अपवाद प्रकार के आधार पर निष्पादित करना चाहते हैं या यदि आप वास्तव में अपवाद के उदाहरण का उपयोग करना चाहते हैं", तो आप बस एक अलग catchब्लॉक बनाते हैं , या आपको इसे किसी भी तरह से डालना होगा .. मेरे अनुभव में, throw;आपके catchब्लॉक में एक शायद एक कोड गंध है।
rgoliveira

@rgoliveira: कैच ब्लॉक में थ्रो का उपयोग करना ठीक है कई मामलों में लिंक देखें । चूंकि केस स्टेटमेंट वास्तव में पैटर्न मिलान लिंक का उपयोग करता है, इसलिए यदि आप एक चर नाम से ऑपरेटर लिंक (अंडरस्कोर) त्यागें, तो आपको कास्ट करने की आवश्यकता नहीं है । मुझे गलत मत समझो, मैं आपसे सहमत हूं कि अपवाद फ़िल्टर एक क्लीनर तरीका है जो कर रहा है, लेकिन कई कैच ब्लॉक बहुत सारे घुंघराले ब्रैकेट जोड़ते हैं।
फेबियन

20

स्वीकृत उत्तर स्वीकार्य लगता है, सिवाय इसके कि CodeAnalysis / FxCop इस तथ्य के बारे में शिकायत करेगा कि यह एक सामान्य अपवाद प्रकार को पकड़ रहा है।

इसके अलावा, ऐसा लगता है कि "है" ऑपरेटर प्रदर्शन को थोड़ा कम कर सकता है।

CA1800: अनावश्यक रूप से मत कहो "के रूप में 'के बजाय' ऑपरेटर के परिणाम के परीक्षण" पर विचार करने के लिए कहते हैं, लेकिन यदि आप ऐसा करते हैं, तो आप प्रत्येक अपवाद को अलग से पकड़ने की तुलना में अधिक कोड लिखेंगे।

किसी भी तरह, यहाँ मैं क्या करूँगा:

bool exThrown = false;

try
{
    // Something
}
catch (FormatException) {
    exThrown = true;
}
catch (OverflowException) {
    exThrown = true;
}

if (exThrown)
{
    // Something else
}

19
लेकिन ध्यान रखें कि यदि आप इस तरह से करते हैं तो स्टैक ट्रेस खोए बिना आप अपवाद को नहीं हटा सकते। (स्वीकृत उत्तर के लिए माइकल स्टम की टिप्पणी देखें)
रेन

2
अपवाद को संग्रहीत करके इस पैटर्न में सुधार किया जा सकता है (कृपया खराब स्वरूपण का बहाना करें - मैं यह पता नहीं लगा सकता कि टिप्पणियों में कोड कैसे डाला जाए): अपवाद पूर्व = अशक्त; {// some} को पकड़ने की कोशिश करें (FormatException e) {ex = e; } कैच (ओवरफ्लो एक्ससेप्शन ई) {एक्स = ई; } अगर (पूर्व! = अशक्त) {// कुछ और और पूर्व से
निपटें

3
@JesseWeigert: 1. आप टेक्स्ट का एक हिस्सा मोनो-स्पॉन्टेड फ़ॉन्ट और लाइट ग्रे बैकग्राउंड देने के लिए बैकटिक्स का उपयोग कर सकते हैं। 2. आप अभी भी स्टैकट्रेस सहित मूल अपवाद को पुनर्व्यवस्थित नहीं कर पाएंगे ।
ओलिवर

2
@CleverNeologism हालांकि यह सच हो सकता है कि isऑपरेटर का उपयोग करने से प्रदर्शन पर थोड़ा नकारात्मक प्रभाव पड़ सकता है, यह भी सच है कि एक अपवाद हैंडलर प्रदर्शन के अनुकूलन के बारे में अत्यधिक चिंतित होने की जगह नहीं है। यदि आपका ऐप अपवाद हैंडलर में इतना समय व्यतीत कर रहा है कि वहाँ प्रदर्शन अनुकूलन ऐप प्रदर्शन में वास्तविक अंतर लाएगा, तो हार्ड कोड लेने के लिए अन्य कोड मुद्दे हैं। यह कहने के बाद कि, मुझे अभी भी यह समाधान पसंद नहीं है क्योंकि आप स्टैक ट्रेस खो देते हैं और क्योंकि क्लीनअप को कैच स्टेटमेंट से हटा दिया जाता है।
क्रेग

3
isजब आप बाद में कोई asऑपरेशन करते हैं तो केवल ऑपरेटर का प्रदर्शन कम हो जाता है (इसलिए वे अनावश्यक रूप से नियम को योग्य बनाते हैं )। यदि आप सभी कर रहे हैं, तो कलाकारों को वास्तव में कलाकारों के प्रदर्शन की आवश्यकता के बिना परीक्षण कर रहा है, तो isऑपरेटर ठीक वही है जो आप उपयोग करना चाहते हैं।
नमस्कार

19

C # 6 में अनुशंसित दृष्टिकोण अपवाद फिल्टर का उपयोग करने के लिए है, यहाँ एक उदाहरण है:

 try
 {
      throw new OverflowException();
 }
 catch(Exception e ) when ((e is DivideByZeroException) || (e is OverflowException))
 {
       // this will execute iff e is DividedByZeroEx or OverflowEx
       Console.WriteLine("E");
 }

18

यह मैट के उत्तर का एक प्रकार है (मुझे लगता है कि यह थोड़ा क्लीनर है) ... एक विधि का उपयोग करें:

public void TryCatch(...)
{
    try
    {
       // something
       return;
    }
    catch (FormatException) {}
    catch (OverflowException) {}

    WebId = Guid.Empty;
}

किसी भी अन्य अपवाद को फेंक दिया जाएगा और कोड WebId = Guid.Empty;को हिट नहीं किया जाएगा। यदि आप अपने प्रोग्राम को क्रैश करने के लिए अन्य अपवाद नहीं चाहते हैं, तो बस इस दो अन्य कैच को जोड़ें:

...
catch (Exception)
{
     // something, if anything
     return; // only need this if you follow the example I gave and put it all in a method
}

-1 यह WebId = Guid.Emtpyउस मामले में निष्पादित करेगा जहां कोई अपवाद नहीं फेंका गया था।
सिपाही

4
@sepster मुझे लगता है कि "// कुछ" के बाद रिटर्न स्टेटमेंट यहाँ निहित है। मुझे वास्तव में समाधान पसंद नहीं है, लेकिन यह चर्चा में एक रचनात्मक रूप है। +1 अपने
डाउनवोट

@ सिस्टर टोंग सही है, मैंने मान लिया कि अगर आप वहां वापसी चाहते हैं, तो आप एक डाल देंगे ... मैं अपने उत्तर को सामान्य बनाने की कोशिश कर रहा था कि सभी स्थितियों में समान रूप से दूसरों के लिए लागू हो, लेकिन सटीक प्रश्नों के रूप में लाभ नहीं होगा कुंआ। हालांकि, अच्छे उपाय के लिए, मैंने returnअपने उत्तर में एक जोड़ दिया है। इनपुट के लिए धन्यवाद।
bsara

18

जोसेफ Daigle का उत्तर एक अच्छा समाधान है, लेकिन मुझे निम्नलिखित संरचना थोड़ी कठिन और कम त्रुटि वाली हो गई।

catch(Exception ex)
{   
    if (!(ex is SomeException || ex is OtherException)) throw;

    // Handle exception
}

अभिव्यक्ति को प्रभावित करने के कुछ फायदे हैं:

  • वापसी विवरण आवश्यक नहीं है
  • कोड नेस्टेड नहीं है
  • जोसेफ के समाधान में अभिव्यक्ति से अलग किए गए 'थ्रो' या 'रिटर्न' बयानों को भूलने का कोई जोखिम नहीं है।

यह भी एक लाइन (हालांकि बहुत सुंदर नहीं) के लिए तैयार किया जा सकता है

catch(Exception ex) { if (!(ex is SomeException || ex is OtherException)) throw;

    // Handle exception
}

संपादित करें: अपवाद को छानने सी # 6.0 में वाक्य रचना थोड़ा क्लीनर कर देगा और एक के साथ आता है अन्य लाभों की संख्या किसी भी वर्तमान समाधान से अधिक। (सबसे विशेष रूप से ढेर को छोड़कर)

यहां बताया गया है कि C # 6.0 सिंटैक्स का उपयोग करके एक ही समस्या कैसे दिखाई देगी:

catch(Exception ex) when (ex is SomeException || ex is OtherException)
{
    // Handle exception
}

2
+1, यह सबसे अच्छा जवाब है। यह शीर्ष उत्तर की तुलना में बेहतर है क्योंकि अधिकतर नहीं है return, हालांकि स्थिति को थोड़ा बेहतर बनाना है।
DCShannon

मैंने ऐसा सोचा भी नहीं था। अच्छी पकड़ है, मैं इसे सूची में जोड़ दूंगा।
स्टीफन टी

16

@Micheal

आपके कोड का थोड़ा संशोधित संस्करण:

catch (Exception ex)
{
   Type exType = ex.GetType();
   if (exType == typeof(System.FormatException) || 
       exType == typeof(System.OverflowException)
   {
       WebId = Guid.Empty;
   } else {
      throw;
   }
}

स्ट्रिंग तुलना बदसूरत और धीमी है।


21
केवल "कीवर्ड" का उपयोग क्यों नहीं किया जाता है?
क्रिस पिसेट्समैन

29
@ मिचेल - यदि Microsoft ने कहा, StringTooLongException FormatException से लिया गया है, तो यह अभी भी एक प्रारूप अपवाद है, बस एक विशिष्ट। यह निर्भर करता है कि क्या आप 'इस सटीक अपवाद प्रकार को पकड़ते हैं' या 'अपवादों को पकड़ने का अर्थ है कि स्ट्रिंग का प्रारूप गलत था'।
ग्रेग बीच

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

14
@ एलेक्स नंबर "थ्रो" के बिना "मूल" मूल स्टैक ट्रेस सहित मूल अपवाद को उठाता है। "पूर्व" जोड़ने से स्टैक ट्रेस रीसेट हो जाता है, इसलिए आपको वास्तव में मूल की तुलना में एक अलग अपवाद मिलता है। मुझे यकीन है कि कोई और इसे मुझसे बेहतर समझा सकता है। :)
सामन्था ब्रांथम

13
-1: यह कोड बेहद नाजुक है - एक लाइब्रेरी डेवलपर लाइब्रेरी का उपयोग किए बिना ब्रेकिंग कोड के throw new FormatException();साथ प्रतिस्थापित करने की उम्मीद कर सकता है throw new NewlyDerivedFromFormatException();, और यह सभी अपवाद हैंडलिंग मामलों के लिए सच होगा, जहां किसी के ==बजाय is(या बस catch (FormatException)) का उपयोग किया जाता है ।
सैम हरवेल

13

कैसा रहेगा

try
{
    WebId = Guid.Empty;
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
}
catch (OverflowException)
{
}

यह तभी काम करता है जब कैच-कोड को पूरी तरह से ट्राई-ब्लॉक में ले जाया जा सकता है। लेकिन इमेजिंग कोड जहां आप किसी ऑब्जेक्ट में कई जोड़तोड़ करते हैं, और बीच में से एक विफल हो जाता है, और आप ऑब्जेक्ट को "रीसेट" करना चाहते हैं।
माइकल Stum

4
उस स्थिति में मैं एक रीसेट फ़ंक्शन जोड़ूंगा और कई कैच ब्लॉक से कॉल करूंगा।
मौरिस


11

सावधानी और चेतावनी: फिर भी एक अन्य प्रकार, कार्यात्मक शैली।

लिंक में जो है वह आपके प्रश्न का सीधे उत्तर नहीं देता है, लेकिन यह देखने के लिए इसे विस्तारित करने के लिए तुच्छ है:

static void Main() 
{ 
    Action body = () => { ...your code... };

    body.Catch<InvalidOperationException>() 
        .Catch<BadCodeException>() 
        .Catch<AnotherException>(ex => { ...handler... })(); 
}

(मूल रूप से एक और खाली प्रदान करें Catch अधिभार करता है जो स्वयं लौटता है)

बड़ा सवाल यह है कि क्यों । मुझे नहीं लगता कि लागत यहाँ लाभ से अधिक है :)


1
इस दृष्टिकोण का एक संभावित लाभ यह है कि अपवाद को पकड़ने और फिर से न फेंकने और इसे न पकड़ने के बीच एक अर्थपूर्ण अंतर है; कुछ मामलों में, कोड को बिना किसी अपवाद के कार्य करना चाहिए । Vb.net में ऐसा संभव है, लेकिन C # में नहीं जब तक कि कोई vb.net में लिखे रैपर का उपयोग न करे और C # से कॉल न किया जाए।
Supercat

1
इसे पकड़े बिना अपवाद पर कार्रवाई कैसे होती है? मैं आपको पूरी तरह से नहीं समझता।
नवफाल

@nawful ... vb फिल्टर - फंक्शन फिल्ट (अपवाद के रूप में) का उपयोग करते हुए: लॉग एक्स (एक्स): वापस लौटें ... फिर कैच लाइन में: कैच एक्स एक्स जब
फिल्ट

1
@FastAl क्या यह अपवाद-फ़िल्टर C # 6 में अनुमति नहीं देता है?
हिमब्रोबेरे

@HimBromBeere हां वे सीधे एनालॉग हैं
FastAl

9

अद्यतन 2015-12-15: https://stackoverflow.com/a/22864936/1718702 देखें सी # 6 के लिए । यह भाषा में एक क्लीनर और अब मानक है।

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

मेरी लाइब्रेरी में मेरा विस्तार पहले से ही था, मूल रूप से अन्य उद्देश्यों के लिए लिखा गया था, लेकिन typeअपवादों की जाँच के लिए इसने पूरी तरह से काम किया । इसके अलावा, imho, यह ||बयानों के एक समूह की तुलना में क्लीनर दिखता है । इसके अलावा, स्वीकृत उत्तर के विपरीत, मैं स्पष्ट अपवादों को संभालना पसंद करता हूं ताकि ex is ...अनिर्दिष्ट व्यवहार हो क्योंकि वंचित वर्ग वहाँ माता-पिता के प्रकारों के लिए उत्तरदायी हैं)।

प्रयोग

if (ex.GetType().IsAnyOf(
    typeof(FormatException),
    typeof(ArgumentException)))
{
    // Handle
}
else
    throw;

IsAnyOf.cs एक्सटेंशन (निर्भरता के लिए पूर्ण त्रुटि हैंडलिंग उदाहरण देखें)

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter matches at least one of the passed in comparisons.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_comparisons">Values to compare against.</param>
        /// <returns>True if a match is found.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static bool IsAnyOf<T>(this T p_parameter, params T[] p_comparisons)
        {
            // Validate
            p_parameter
                .CannotBeNull("p_parameter");
            p_comparisons
                .CannotBeNullOrEmpty("p_comparisons");

            // Test for any match
            foreach (var item in p_comparisons)
                if (p_parameter.Equals(item))
                    return true;

            // Return no matches found
            return false;
        }
    }
}

पूर्ण त्रुटि हैंडलिंग उदाहरण (कॉपी-पेस्ट को नए कंसोल ऐप)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.FluentValidation;

namespace IsAnyOfExceptionHandlerSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // High Level Error Handler (Log and Crash App)
            try
            {
                Foo();
            }
            catch (OutOfMemoryException ex)
            {
                Console.WriteLine("FATAL ERROR! System Crashing. " + ex.Message);
                Console.ReadKey();
            }
        }

        static void Foo()
        {
            // Init
            List<Action<string>> TestActions = new List<Action<string>>()
            {
                (key) => { throw new FormatException(); },
                (key) => { throw new ArgumentException(); },
                (key) => { throw new KeyNotFoundException();},
                (key) => { throw new OutOfMemoryException(); },
            };

            // Run
            foreach (var FooAction in TestActions)
            {
                // Mid-Level Error Handler (Appends Data for Log)
                try
                {
                    // Init
                    var SomeKeyPassedToFoo = "FooParam";

                    // Low-Level Handler (Handle/Log and Keep going)
                    try
                    {
                        FooAction(SomeKeyPassedToFoo);
                    }
                    catch (Exception ex)
                    {
                        if (ex.GetType().IsAnyOf(
                            typeof(FormatException),
                            typeof(ArgumentException)))
                        {
                            // Handle
                            Console.WriteLine("ex was {0}", ex.GetType().Name);
                            Console.ReadKey();
                        }
                        else
                        {
                            // Add some Debug info
                            ex.Data.Add("SomeKeyPassedToFoo", SomeKeyPassedToFoo.ToString());
                            throw;
                        }
                    }
                }
                catch (KeyNotFoundException ex)
                {
                    // Handle differently
                    Console.WriteLine(ex.Message);

                    int Count = 0;
                    if (!Validate.IsAnyNull(ex, ex.Data, ex.Data.Keys))
                        foreach (var Key in ex.Data.Keys)
                            Console.WriteLine(
                                "[{0}][\"{1}\" = {2}]",
                                Count, Key, ex.Data[Key]);

                    Console.ReadKey();
                }
            }
        }
    }
}

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter matches at least one of the passed in comparisons.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_comparisons">Values to compare against.</param>
        /// <returns>True if a match is found.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static bool IsAnyOf<T>(this T p_parameter, params T[] p_comparisons)
        {
            // Validate
            p_parameter
                .CannotBeNull("p_parameter");
            p_comparisons
                .CannotBeNullOrEmpty("p_comparisons");

            // Test for any match
            foreach (var item in p_comparisons)
                if (p_parameter.Equals(item))
                    return true;

            // Return no matches found
            return false;
        }

        /// <summary>
        /// Validates if any passed in parameter is equal to null.
        /// </summary>
        /// <param name="p_parameters">Parameters to test for Null.</param>
        /// <returns>True if one or more parameters are null.</returns>
        public static bool IsAnyNull(params object[] p_parameters)
        {
            p_parameters
                .CannotBeNullOrEmpty("p_parameters");

            foreach (var item in p_parameters)
                if (item == null)
                    return true;

            return false;
        }
    }
}

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter is not null, throwing a detailed exception message if the test fails.
        /// </summary>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_name">Name of tested parameter to assist with debugging.</param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void CannotBeNull(this object p_parameter, string p_name)
        {
            if (p_parameter == null)
                throw
                    new
                        ArgumentNullException(
                        string.Format("Parameter \"{0}\" cannot be null.",
                        p_name), default(Exception));
        }
    }
}

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter is not null or an empty collection, throwing a detailed exception message if the test fails.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_name">Name of tested parameter to assist with debugging.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static void CannotBeNullOrEmpty<T>(this ICollection<T> p_parameter, string p_name)
        {
            if (p_parameter == null)
                throw new ArgumentNullException("Collection cannot be null.\r\nParameter_Name: " + p_name, default(Exception));

            if (p_parameter.Count <= 0)
                throw new ArgumentOutOfRangeException("Collection cannot be empty.\r\nParameter_Name: " + p_name, default(Exception));
        }

        /// <summary>
        /// Validates the passed in parameter is not null or empty, throwing a detailed exception message if the test fails.
        /// </summary>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_name">Name of tested parameter to assist with debugging.</param>
        /// <exception cref="ArgumentException"></exception>
        public static void CannotBeNullOrEmpty(this string p_parameter, string p_name)
        {
            if (string.IsNullOrEmpty(p_parameter))
                throw new ArgumentException("String cannot be null or empty.\r\nParameter_Name: " + p_name, default(Exception));
        }
    }
}

दो सैंपल NUnit यूनिट टेस्ट

Exceptionप्रकारों के लिए मैचिंग व्यवहार सटीक है (यानी एक बच्चा अपने माता-पिता के किसी भी प्रकार के लिए मैच नहीं है)।

using System;
using System.Collections.Generic;
using Common.FluentValidation;
using NUnit.Framework;

namespace UnitTests.Common.Fluent_Validations
{
    [TestFixture]
    public class IsAnyOf_Tests
    {
        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void IsAnyOf_ArgumentNullException_ShouldNotMatch_ArgumentException_Test()
        {
            Action TestMethod = () => { throw new ArgumentNullException(); };

            try
            {
                TestMethod();
            }
            catch (Exception ex)
            {
                if (ex.GetType().IsAnyOf(
                    typeof(ArgumentException), /*Note: ArgumentNullException derrived from ArgumentException*/
                    typeof(FormatException),
                    typeof(KeyNotFoundException)))
                {
                    // Handle expected Exceptions
                    return;
                }

                //else throw original
                throw;
            }
        }

        [Test, ExpectedException(typeof(OutOfMemoryException))]
        public void IsAnyOf_OutOfMemoryException_ShouldMatch_OutOfMemoryException_Test()
        {
            Action TestMethod = () => { throw new OutOfMemoryException(); };

            try
            {
                TestMethod();
            }
            catch (Exception ex)
            {
                if (ex.GetType().IsAnyOf(
                    typeof(OutOfMemoryException),
                    typeof(StackOverflowException)))
                    throw;

                /*else... Handle other exception types, typically by logging to file*/
            }
        }
    }
}

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

1
या कुछ शब्दों में: मूल रूप से प्रदान की जाने वाली भाषा के साथ चिपके रहते हैं। किसी भाषा के शब्दार्थ को ओवरराइड करने का प्रयास न करें, केवल इसलिए कि आप उन्हें पसंद नहीं करते हैं। आपके कॉलेजियम (और संभवत: भविष्य-मेरे) आपको, ईमानदारी से धन्यवाद देंगे।
काई

यह भी ध्यान दें, आपका समाधान केवल C # 6 के शब्दार्थ का अनुमान लगाता है when, जैसा कि किसी भी संस्करण का होगा catch (Exception ex) {if (...) {/*handle*/} throw;}। इसका वास्तविक मूल्य whenयह है कि फ़िल्टर पकड़े जाने से पहले चलता है , इस प्रकार पुनः फेंकने के खर्च / ढेर भ्रष्टाचार से बचा जाता है। यह सीएलआर सुविधा का लाभ उठाता है जो केवल पहले वीबी और एमएसआईएल के लिए सुलभ थी।
मार्क एल।

और अधिक सुंदर? इस तरह की सरल समस्या के लिए यह उदाहरण बहुत बड़ा है और कोड इतना भयानक है कि यह देखने लायक भी नहीं है। कृपया इस कोड को वास्तविक परियोजना पर किसी और की समस्या न बनाएं।
KthProg

आपकी पूरी IsAnyOfविधि को फिर से लिखा जा सकता हैp_comparisons.Contains(p_parameter)
maksymiuk

7

जब से मुझे लगा कि ये उत्तर सिर्फ सतह को छूते हैं, मैंने थोड़ा गहरा खुदाई करने का प्रयास किया।

तो जो हम वास्तव में करना चाहते हैं वह कुछ ऐसा है जो संकलन नहीं करता है:

// Won't compile... damn
public static void Main()
{
    try
    {
        throw new ArgumentOutOfRangeException();
    }
    catch (ArgumentOutOfRangeException)
    catch (IndexOutOfRangeException) 
    {
        // ... handle
    }

इसका कारण हम यह चाहते हैं क्योंकि हम नहीं चाहते हैं कि अपवाद हैंडलर उन चीजों को पकड़े जो हमें बाद में प्रक्रिया में चाहिए। निश्चित रूप से, हम एक अपवाद को पकड़ सकते हैं और 'अगर' क्या करना है के साथ जांच कर सकते हैं, लेकिन चलो ईमानदार रहें, हम वास्तव में ऐसा नहीं चाहते हैं। (FxCop, डिबगर मुद्दों, बदसूरती)

तो यह कोड क्यों नहीं संकलित होगा - और हम इसे इस तरह से कैसे हैक कर सकते हैं कि यह होगा?

यदि हम कोड को देखते हैं, तो हम वास्तव में क्या करना चाहते हैं, कॉल अग्रेषित करता है। हालाँकि, MS विभाजन II के अनुसार, IL अपवाद हैंडलर ब्लॉक इस तरह से काम नहीं करेगा, जो इस मामले में समझ में आता है क्योंकि इसका मतलब यह होगा कि 'अपवाद' ऑब्जेक्ट के विभिन्न प्रकार हो सकते हैं।

या इसे कोड में लिखने के लिए, हम कंपाइलर को कुछ ऐसा करने के लिए कहते हैं (वैसे यह पूरी तरह से सही नहीं है, लेकिन यह मेरे द्वारा अनुमानित निकटतम संभव बात है):

// Won't compile... damn
try
{
    throw new ArgumentOutOfRangeException();
}
catch (ArgumentOutOfRangeException e) {
    goto theOtherHandler;
}
catch (IndexOutOfRangeException e) {
theOtherHandler:
    Console.WriteLine("Handle!");
}

इसका कारण यह नहीं होगा कि यह स्पष्ट है: '$ अपवाद' ऑब्जेक्ट का प्रकार और मान क्या है (जो कि यहाँ 'e' में संग्रहीत हैं)? जिस तरह से हम संकलक को इसे संभालना चाहते हैं, वह ध्यान दें कि दोनों अपवादों का सामान्य आधार प्रकार 'अपवाद' है, एक चर के लिए दोनों अपवादों का उपयोग करें और फिर पकड़े गए केवल दो अपवादों को संभालें। इसे IL में लागू करने का तरीका 'फ़िल्टर' के रूप में है, जो VB.Net में उपलब्ध है।

C # में इसे काम करने के लिए, हमें सही 'अपवाद' आधार प्रकार के साथ एक अस्थायी चर की आवश्यकता है। कोड के प्रवाह को नियंत्रित करने के लिए, हम कुछ शाखाओं को जोड़ सकते हैं। यहाँ जाता हैं:

    Exception ex;
    try
    {
        throw new ArgumentException(); // for demo purposes; won't be caught.
        goto noCatch;
    }
    catch (ArgumentOutOfRangeException e) {
        ex = e;
    }
    catch (IndexOutOfRangeException e) {
        ex = e;
    }

    Console.WriteLine("Handle the exception 'ex' here :-)");
    // throw ex ?

noCatch:
    Console.WriteLine("We're done with the exception handling.");

इसके लिए स्पष्ट नुकसान यह है कि हम ठीक से फेंक नहीं सकते हैं, और चलो ईमानदार होना चाहिए - कि यह काफी बदसूरत समाधान है। शाखा उन्मूलन के द्वारा कुरूपता को थोड़ा ठीक किया जा सकता है, जो समाधान को थोड़ा बेहतर बनाता है:

Exception ex = null;
try
{
    throw new ArgumentException();
}
catch (ArgumentOutOfRangeException e)
{
    ex = e;
}
catch (IndexOutOfRangeException e)
{
    ex = e;
}
if (ex != null)
{
    Console.WriteLine("Handle the exception here :-)");
}

वह सिर्फ leaves री-थ्रो ’छोड़ता है। इस काम के लिए, हमें 'कैच' ब्लॉक के अंदर हैंडलिंग करने में सक्षम होना चाहिए - और इस काम को करने का एकमात्र तरीका 'एक्सेप्शन' ऑब्जेक्ट को पकड़ना है।

इस बिंदु पर, हम एक अलग फ़ंक्शन जोड़ सकते हैं जो विभिन्न प्रकार के अपवादों को अधिभार संकल्प का उपयोग करके संभालता है, या अपवाद को संभालने के लिए। दोनों के नुकसान हैं। शुरू करने के लिए, यह एक सहायक कार्य के साथ करने का तरीका है:

private static bool Handle(Exception e)
{
    Console.WriteLine("Handle the exception here :-)");
    return true; // false will re-throw;
}

public static void Main()
{
    try
    {
        throw new OutOfMemoryException();
    }
    catch (ArgumentException e)
    {
        if (!Handle(e)) { throw; }
    }
    catch (IndexOutOfRangeException e)
    {
        if (!Handle(e)) { throw; }
    }

    Console.WriteLine("We're done with the exception handling.");

और दूसरा उपाय यह है कि एक्सेप्शन ऑब्जेक्ट को पकड़ा जाए और उसी के अनुसार उसे हैंडल किया जाए। इसके लिए सबसे शाब्दिक अनुवाद, उपरोक्त संदर्भ पर आधारित है:

try
{
    throw new ArgumentException();
}
catch (Exception e)
{
    Exception ex = (Exception)(e as ArgumentException) ?? (e as IndexOutOfRangeException);
    if (ex != null)
    {
        Console.WriteLine("Handle the exception here :-)");
        // throw ?
    }
    else 
    {
        throw;
    }
}

इसलिए निष्कर्ष निकालना:

  • यदि हम फिर से फेंकना नहीं चाहते हैं, तो हम सही अपवादों को पकड़ने पर विचार कर सकते हैं, और उन्हें अस्थायी रूप से संग्रहीत कर सकते हैं।
  • यदि हैंडलर सरल है, और हम कोड का फिर से उपयोग करना चाहते हैं, तो सबसे अच्छा समाधान शायद एक सहायक फ़ंक्शन को पेश करना है।
  • अगर हम फिर से फेंकना चाहते हैं, तो हमारे पास कोड को 'एक्सेप्शन' कैच हैंडलर में रखने के अलावा कोई चारा नहीं है, जो FxCop और आपके डिबगर के अनकैप्ड अपवादों को तोड़ देगा।

7

यह एक क्लासिक समस्या है जो हर C # डेवलपर को अंततः झेलनी पड़ती है।

मुझे आपके प्रश्न को 2 प्रश्नों में तोड़ने दें। सबसे पहला,

क्या मैं एक साथ कई अपवादों को पकड़ सकता हूं?

संक्षेप में, नहीं।

जो अगले प्रश्न की ओर जाता है,

मैं दिए गए डुप्लिकेट कोड को लिखने से कैसे बचता हूं कि मैं एक ही कैच () ब्लॉक में कई अपवाद प्रकार नहीं पकड़ सकता हूं?

आपके विशिष्ट नमूने को देखते हुए, जहां निर्माण के लिए गिरावट-वापस मूल्य सस्ता है, मुझे इन चरणों का पालन करना पसंद है:

  1. प्रारंभिक मूल्य में वापस आने के लिए WebId।
  2. एक अस्थायी चर में एक नया गाइड का निर्माण।
  3. WebId को पूरी तरह से निर्मित अस्थायी चर पर सेट करें। इसे {} ब्लॉक की कोशिश का अंतिम विवरण दें।

तो कोड जैसा दिखता है:

try
{
    WebId = Guid.Empty;
    Guid newGuid = new Guid(queryString["web"]);
    // More initialization code goes here like 
    // newGuid.x = y;
    WebId = newGuid;
}
catch (FormatException) {}
catch (OverflowException) {}

यदि कोई अपवाद फेंका जाता है, तो WebId को कभी भी आधे-अधूरे मूल्य पर सेट नहीं किया जाता है, और मार्गदर्शक रहता है।

यदि फॉल-बैक वैल्यू का निर्माण करना महंगा है, और एक वैल्यू को रीसेट करना बहुत सस्ता है, तो मैं रीसेट कोड को अपने स्वयं के फ़ंक्शन में स्थानांतरित कर दूंगा:

try
{
    WebId = new Guid(queryString["web"]);
    // More initialization code goes here.
}
catch (FormatException) {
    Reset(WebId);
}
catch (OverflowException) {
    Reset(WebId);
}

यह अच्छा है, "पारिस्थितिक कोडिंग" यानी आप अपने कोड और डेटा फ़ुटप्रिंट के बारे में आगे सोच रहे हैं और सुनिश्चित करें कि आधे संसाधित मूल्यों का कोई रिसाव नहीं है। जेफरी धन्यवाद इस पैटर्न का पालन करने जा रहा है!
ताहिर खालिद

6

तो आप हर अपवाद-स्विच के भीतर बहुत सारे कोड दोहरा रहे हैं? एक विधि निकालने की तरह लगता है भगवान विचार, यह नहीं होगा?

तो आपका कोड इस पर आता है:

MyClass instance;
try { instance = ... }
catch(Exception1 e) { Reset(instance); }
catch(Exception2 e) { Reset(instance); }
catch(Exception) { throw; }

void Reset(MyClass instance) { /* reset the state of the instance */ }

मुझे आश्चर्य है कि किसी ने उस कोड-डुप्लीकेशन को क्यों नहीं देखा।

C # 6 से आप अन्य लोगों द्वारा पहले ही बताए गए अपवाद-फ़िल्टर कर सकते हैं। इसलिए आप ऊपर दिए गए कोड को संशोधित कर सकते हैं:

try { ... }
catch(Exception e) when(e is Exception1 || e is Exception2)
{ 
    Reset(instance); 
}

3
"मुझे आश्चर्य है कि क्यों किसी ने उस कोड-डुप्लीकेशन पर ध्यान नहीं दिया।" - ओह क्या? प्रश्न के पूरे बिंदु कोड डुप्लिकेशन समाप्त करने के लिए है।
मार्क अमेरी

4

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

उदाहरण के लिए यदि आप एक "कैच-ऑल" के रूप में अपवाद का उपयोग अपवाद यह अन्य सभी पकड़ बयान के बाद का होना होगा और आप स्पष्ट रूप से संकलक त्रुटियों तथापि मिल जाएगा अगर आप (अपनी पकड़ बयान अप आपको श्रृंखला कर सकते हैं रिवर्स एक विरोधी पैटर्न मुझे लगता है कि बिट ) आप कैच-ऑल अपवाद अपवाद को नीचे रख सकते हैं और यह किसी भी अपवाद को कैप्चर करेगा जो आपके try..catch ब्लॉक में उच्चतर के लिए पूरा नहीं किया है:

            try
            {
                // do some work here
            }
            catch (WebException ex)
            {
                // catch a web excpetion
            }
            catch (ArgumentException ex)
            {
                // do some stuff
            }
            catch (Exception ex)
            {
                // you should really surface your errors but this is for example only
                throw new Exception("An error occurred: " + ex.Message);
            }

मैं अत्यधिक अनुशंसा करता हूं कि लोग इस MSDN दस्तावेज़ की समीक्षा करें:

अपवाद पदानुक्रम


4

हो सकता है कि अपने कोड को सरल रखने की कोशिश करें जैसे कि कॉमन कोड को एक विधि में रखना, जैसा कि आप कोड के किसी अन्य भाग में करेंगे जो कैच क्लॉज के अंदर नहीं है?

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

try
{
    // ...
}
catch (FormatException)
{
    DoSomething();
}
catch (OverflowException)
{
    DoSomething();
}

// ...

private void DoSomething()
{
    // ...
}

बस मैं इसे कैसे करूँगा, सरल सुंदर पैटर्न को खोजने की कोशिश कर रहा हूं


3

ध्यान दें कि मुझे इसे करने का एक तरीका मिला, लेकिन यह द डेली डब्ल्यूटीएफ के लिए सामग्री की तरह दिखता है :

catch (Exception ex)
{
    switch (ex.GetType().Name)
    {
        case "System.FormatException":
        case "System.OverflowException":
            WebId = Guid.Empty;
            break;
        default:
            throw;
    }
}

9
-1 वोट, +5 डब्ल्यूटीएफ :-) यह एक जवाब के रूप में चिह्नित नहीं किया जाना चाहिए था, लेकिन यह वह बड़ा है।
आरोन

1
इससे कोई फर्क नहीं पड़ता कि हम इसे कैसे कर सकते हैं। लेकिन वह बेकार नहीं बैठे और इसे हल करने के लिए अपने दृष्टिकोण के साथ आए। वास्तव में सराहना।
मैक्सिमस

2
हालांकि, ऐसा वास्तव में नहीं करते हैं, C # 6 या अन्य उत्तरों में अपवाद फ़िल्टर का उपयोग करें - मैंने इसे विशेष रूप से "यह एक तरीका है, लेकिन इसे बुरा माना है और मैं कुछ बेहतर करना चाहता हूं"।
माइकल Stum

यह बुरा क्यों है? मैं हैरान था कि आप सीधे एक स्विच स्टेटमेंट में अपवाद का उपयोग नहीं कर सकते थे।
MKesper

3
@MKperper मुझे कुछ कारण दिखाई देते हैं जो खराब है। इसके लिए पूरी तरह से योग्य वर्ग के नाम को स्ट्रिंग शाब्दिक के रूप में लिखने की आवश्यकता होती है, जो टाइपोस के लिए कमजोर है जो संकलक आपको नहीं बचा सकता है। (यह बहुत महत्वपूर्ण है क्योंकि कई दुकानों में त्रुटि के मामले कम अच्छी तरह से जांचे जाते हैं और इसलिए उनमें बहुत छोटी गलतियां होने की संभावना होती है।) यह एक अपवाद से मेल खाने में भी विफल होगा जो कि निर्दिष्ट मामलों में से एक का उपवर्ग है। और, तार होने के कारण, वीएस के "फाइंड ऑल रिफरेंस" जैसे उपकरणों से मामले छूट जाएंगे - यदि आप हर जगह एक सफाई कदम जोड़ना चाहते हैं तो एक विशेष अपवाद पकड़ा जाता है।
मार्क अमेरी

2

यहाँ यह ध्यान देने योग्य है। आप कई संयोजनों (अपवाद त्रुटि और अपवाद.समूह) का जवाब दे सकते हैं।

जब मैं टेक्स्ट बॉक्स, टेक्स्टब्लॉक या चेकबॉक्स जैसी सामग्री के साथ डेटाग्रिड में नियंत्रण ऑब्जेक्ट को डालने की कोशिश कर रहा था, तो मैं एक केस केस परिदृश्य में भाग गया। इस मामले में लौटा हुआ अपवाद समान था, लेकिन संदेश विविध था।

try
{
 //do something
}
catch (Exception ex) when (ex.Message.Equals("the_error_message1_here"))
{
//do whatever you like
} 
catch (Exception ex) when (ex.Message.Equals("the_error_message2_here"))
{
//do whatever you like
} 

0

मैं सबसे छोटा जवाब देना चाहता हूं (एक और कार्यात्मक शैली ):

        Catch<FormatException, OverflowException>(() =>
            {
                WebId = new Guid(queryString["web"]);
            },
            exception =>
            {
                WebId = Guid.Empty;
            });

इसके लिए आपको System.Action के समान कई "कैच" विधि ओवरलोड्स बनाने होंगे।

    [DebuggerNonUserCode]
    public static void Catch<TException1, TException2>(Action tryBlock,
        Action<Exception> catchBlock)
    {
        CatchMany(tryBlock, catchBlock, typeof(TException1), typeof(TException2));
    }

    [DebuggerNonUserCode]
    public static void Catch<TException1, TException2, TException3>(Action tryBlock,
        Action<Exception> catchBlock)
    {
        CatchMany(tryBlock, catchBlock, typeof(TException1), typeof(TException2), typeof(TException3));
    }

और आप चाहते हैं कि इतने पर। लेकिन आपको इसे एक बार करने की आवश्यकता है और आप इसे अपनी सभी परियोजनाओं में उपयोग कर सकते हैं (या, यदि आपने एक नौगट पैकेज बनाया है तो हम भी इसका उपयोग कर सकते हैं)।

और कैचमनी कार्यान्वयन:

    [DebuggerNonUserCode]
    public static void CatchMany(Action tryBlock, Action<Exception> catchBlock,
        params Type[] exceptionTypes)
    {
        try
        {
            tryBlock();
        }
        catch (Exception exception)
        {
            if (exceptionTypes.Contains(exception.GetType())) catchBlock(exception);
            else throw;
        }
    }

ps मैंने कोड सादगी के लिए अशक्त जांच नहीं रखी है, पैरामीटर सत्यापन जोड़ने पर विचार करें।

ps2 यदि आप कैच से वैल्यू लौटाना चाहते हैं, तो कैच के तरीकों को करना जरूरी है, लेकिन पैरामीटर्स में एक्शन के बजाय रिटर्न और फंक के साथ।


-15

बस कोशिश को बुलाओ और दो बार पकड़ लो।

try
{
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
    WebId = Guid.Empty;
}
try
{
    WebId = new Guid(queryString["web"]);
}
catch (OverflowException)
{
    WebId = Guid.Empty;
}

यह इतना ही सरल है!!


3
उम। यह प्रश्न के उद्देश्य को हरा रहा है। वह यह प्रश्न डुप्लिकेट कोड से छुटकारा पाने के लिए कहता है। यह उत्तर अधिक डुप्लिकेट कोड जोड़ता है।
जेम्स एश

-23

सी # 6.0 में, अपवाद फ़िल्टरिंग अपवाद हैंडलिंग के लिए सुधार है

try
{
    DoSomeHttpRequest();
}
catch (System.Web.HttpException e)
{
    switch (e.GetHttpCode())
    {
        case 400:
            WriteLine("Bad Request");
        case 500:
            WriteLine("Internal Server Error");
        default:
            WriteLine("Generic Error");
    }
}

13
यह उदाहरण अपवाद फ़िल्टर का कोई उपयोग नहीं दिखाता है।
user247702

यह सी # 6.0 में अपवाद को फ़िल्टर करने का मानक तरीका है
काशिफ

5
एक बार फिर देखें कि वास्तव में अपवाद फ़िल्टर क्या हैं। आप अपने उदाहरण में एक अपवाद फ़िल्टर का उपयोग नहीं कर रहे हैं। आपके द्वारा एक वर्ष पहले पोस्ट किए गए इस उत्तर में एक उचित उदाहरण है ।
user247702

6
अपवाद फ़िल्टरिंग का एक उदाहरण होगाcatch (HttpException e) when e.GetHttpCode() == 400 { WriteLine("Bad Request"; }
16:13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.