2012-04-12 18 views
11

मेरे कोड में मैं एक ऐसी स्थिति में आ रहा हूं जिसमें System.Reflection.TargetInvocationException फेंक दिया गया है। एक विशिष्ट मामले में मुझे पता है कि मैं रूट अपवाद को कैसे संभालना चाहता हूं, लेकिन मैं अन्य सभी अपवादों को फेंकना चाहता हूं। मैं ऐसा करने के दो तरीकों के बारे में सोच सकता हूं, लेकिन मुझे यकीन नहीं है कि कौन सा बेहतर है।एक आंतरिक अपवाद के प्रकार की जांच

1.

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    if (typeof(ex.InnerException) == typeof(SpecificException)) 
    { 
     //fix 
    } 
    else 
    { 
     throw ex.Innerexception; 
    } 
} 

2.

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    try 
    { 
     throw ex.InnerException; 
    } 
    catch (SpecificException exSpecific) 
    { 
     //fix 
    } 
} 

मुझे पता है कि सामान्य रूप में अपवाद फेंक धीमी है हूँ, इसलिए मुझे लगता है कि पहली विधि संभवतः तेजी से होगा। वैकल्पिक रूप से, क्या ऐसा करने का एक बेहतर तरीका है जिसके बारे में मैंने सोचा नहीं है?

+2

2, आकर्षक है imho 1 अधिक पठनीय और शायद देखने के एक प्रदर्शन बिंदु से बेहतर है। – Gabber

+0

प्रश्न: 'targetInvocationException' फेंकने वाला कॉल क्या है? क्या यह आपका कोड है, या तीसरी पार्टी है? –

+0

यह जेनरेट कोड है जो डीबी से पढ़ रहा है। – geekchic

उत्तर

17

आपके प्रस्तावित समाधानों में से प्रत्येक का अपना मुद्दा है।

पहली विधि जांचती है कि आंतरिक अपवाद का प्रकार ठीक जिस प्रकार की आप उम्मीद कर रहे हैं। इसका मतलब है कि एक व्युत्पन्न प्रकार मेल नहीं खाएगा, जो आपके इरादे से नहीं हो सकता है।

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

try 
{ 
    // Do something 
} 
catch (TargetInvocationException ex) 
{ 
    if (ex.InnerException is SpecificException) 
    { 
     // Handle SpecificException 
    } 
    else if (ex.InnerException is SomeOtherSpecificException) 
    { 
     // Handle SomeOtherSpecificException 
    } 
    else 
    { 
     throw; // Always rethrow exceptions you don't know how to handle. 
    } 
} 

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

समाधान क्या DarkGray, पोस्ट निक के सुझाव के साथ और मेरे अपने का एक अतिरिक्त सुझाव (else में) के साथ मूल रूप से है संभाल नहीं है, throw ex; नहीं है क्योंकि इससे स्टैक ट्रेस ओवरराइट हो जाएगा। इसके बजाय throw; का उपयोग करें जो स्टैक ट्रेस को संरक्षित करता है। इसका मूल रूप से अर्थ है "मैं वास्तव में यह catch खंड दर्ज नहीं करना चाहता था, नाटक करता हूं कि मैंने अपवाद कभी नहीं पकड़ा"।

अद्यतन: सी # 6।0 अपवाद फिल्टर के माध्यम से एक बेहतर वाक्य रचना प्रदान करता है:

try 
{ 
    // Do something 
} 
catch (TargetInvocationException ex) when (ex.InnerException is SpecificException) 
{ 
    // Handle SpecificException 
} 
catch (TargetInvocationException ex) when (ex.InnerException is SomeOtherSpecificException) 
{ 
    // Handle SomeOtherSpecificException 
} 
+0

+1 और 'पूर्व फेंक'; – geekchic

-2
try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    if (ex.InnerException is SpecificException) 
    { 
     //fix 
    } 
    else 
    { 
     throw ex.InnerException; 
    } 
} 

या

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    SpecificException spExc = ex.InnerException as SpecificException; 
    if (spExc != null) 
    { 
     bla-bla spExc 
    } 
    else 
    { 
     throw ex.InnerException; 
    } 
} 

या

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    if (ex.InnerException.GetType() == typeof(SpecificException)) 
    { 
     //fix 
    } 
    else 
    { 
     throw ex.InnerException; 
    } 
} 
+0

'is' कीवर्ड का उपयोग क्यों नहीं करें? – Nick

+0

आपका कोड मूल पहले सुझाव के लिए कोई अलग कार्य नहीं है, और आपने कोड के लिए कोई तर्क या औचित्य प्रदान नहीं किया है। 'फेंक' के बीच अंतर को इंगित करने के लिए –

1

आपका # 2 निश्चित रूप से एक दिलचस्प हल है!

आप हालांकि सावधान रहना होगा करना चाहते हैं: TargetInvocationException आम तौर पर एक और घटक द्वारा फेंका गया होगा जब वह पहली बार InnerException पकड़ लिया। यदि आप throw ex.InnerException हैं तो इसमें कुछ जानकारी नष्ट हो जाएगी (जैसे स्टैक ट्रेस) क्योंकि आप इसे किसी दूसरे स्थान से फिर से फेंक रहे हैं।

तो आपने प्रस्तावित दो में से, मैं निश्चित रूप से # 1 के साथ जाने का सुझाव दूंगा। मुझे आपके द्वारा प्राप्त संरचना के भीतर एक विकल्प के बारे में पता नहीं है। हालांकि, इनरएक्सप्शन को मूल रूप से कहीं और फेंक दिया जाएगा - यह जांच करने लायक है कि इस विफलता को संभालने के लिए और अधिक सुरुचिपूर्ण जगह है, जहां अपवाद फेंक दिया गया है।

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