2009-09-23 13 views
34

की इनर एक्सेप्शन सेट करें ऑब्जेक्ट की InnerException प्रॉपर्टी कैसे सेट कर सकता हूं, जबकि मैं उस ऑब्जेक्ट के निर्माता में हूं? यह उस संपत्ति के बैकिंग फ़ील्ड को ढूंढने और सेट करने के लिए उबलता है जिसमें कोई सेटटर नहीं है।.NET अपवाद ऑब्जेक्ट

बीटीडब्ल्यू: मैंने यह देखा है (http://evain.net/blog/articles/2009/05/01/getting-the-field-backing-a-property-using-reflection) लेकिन यदि संभव हो तो गैर आईएल-आधारित समाधान की तलाश में है।

अपवाद निर्माता जगह है जहाँ अपवाद प्रकार बनाया जाता है, तो मैं आधार वर्ग निर्माता MyException() का उपयोग कर यह फोन नहीं कर सकते हैं: आधार (...) आदि

+0

अनुवर्ती अनुवर्ती; तब (जैसा कि मैंने उल्लेख किया है) कन्स्ट्रक्टर के अंदर की बजाय एक स्थिर विधि * आगे * में एक प्रकार का निर्माण करें। –

+1

मेरे मामले में encapsulate करने के लिए और अधिक समझ में आता है। –

+0

... लेकिन मैं आपका मुद्दा लेता हूं, मैं प्रतिबिंब लागत से बचने के लिए इसे एक कारखाना बनाने में देखूंगा। –

उत्तर

12

आप इंजेक्शन अपवाद को पैरामीटर के रूप में क्यों नहीं ले सकते हैं? यह संभव नहीं है किसी कारण के लिए है, तो System.Exception में समर्थन क्षेत्र है:

private Exception _innerException; 

मैं इसे बाहर Redgate's Reflector का उपयोग कर पाया। प्रतिबिंब का उपयोग करना मुझे लगता है कि आप आंतरिक अपवाद सेट कर सकते हैं।

संपादित करें: ज्यादातर मामलों में निजी क्षेत्रों को प्रतिबिंब के माध्यम से एक्सेस करना अच्छा नहीं है, लेकिन मुझे यह सुनिश्चित करने के लिए एनटी के मामले के बारे में पर्याप्त जानकारी नहीं है कि यह एक अच्छा या बुरा विचार है।

+9

मैं एक समझदार उदाहरण के बारे में नहीं सोच सकता जहां प्रतिबिंब ऐसा करने का सही तरीका है ... –

+0

यह अपवादों के सक्रियण से जुड़े गतिशील परिदृश्यों के लिए समझ में आता है जहां आंतरिक अपवाद अग्रिम में नहीं जाना जा सकता है, इसलिए निर्माता को पास नहीं किया जा सकता । –

+3

नहीं, यह नहीं है। यह वास्तव में नहीं करता है; यह encapsulation तोड़ता है। 'स्थिर (कुछ विधि (...), ...) 'श्रृंखला में एक स्थिर विधि का प्रयोग करें। –

7
Exception exceptionWithMoreInfo = new Exception("extra info", ex); 

सामान्य अभ्यास किया जाएगा यह मानते हुए कि आपने एक अपवाद फंस लिया है जिसके लिए आप बुलबुले से पहले अधिक जानकारी जोड़ना चाहते हैं।

public MyException(string message, Exception innerException) 
     : base(message, innerException) {...} 

आप अपवाद पाने के लिए कुछ कोड को चलाने के लिए की जरूरत है, एक स्थिर विधि का उपयोग करें:

+1

यह हालांकि, अपवाद के ctor में आपकी मदद नहीं करता है। – Joey

59

आप आधार ctor फोन करके भीतरी अपवाद सेट

public MyException(SomeData data) : base(GetMessage(data), GetInner(data)) {...} 
static Exception GetInner(SomeData data) {...} // <===== your type creation here! 
static string GetMessage(SomeData data) {...} 
1

InnerException नहीं है Exception(string, Exception) कन्स्ट्रक्टर का उपयोग करते समय सेट किया जाना चाहिए? मुझे लगता है कि यह डिजाइन द्वारा है कि आप इस अन्यथा नहीं बदल सकते हैं लेकिन आप हमेशा निर्माण समय में उचित निर्माता के लिए स्थगित कर सकते हैं:

class MyException : Exception { 
    public MyException() 
     : base("foo", new Exception("bar")) 
    { 
     ... 
    } 

    ... 
} 

मुझे लगता है कि आप जब से कि आम तौर पर अपने कोड में अपवाद श्रृंखला को तोड़ने नहीं करना चाहिए त्रुटियों की ओर जाता है जो आपको फिर कभी नहीं मिलेगा।

Exception exc = new Exception("message", new Exception("inner message")); 

यह आपके लिए क्या देख रहे है:

29

Exception वर्ग एक ओवरलोड निर्माता एक पैरामीटर के रूप भीतरी अपवाद को स्वीकार है?

+0

जबकि यह सीधे अपने प्रश्न का उत्तर नहीं देता है, यह जवाब देता है कि इसके लिए खोजे जाने वाले अधिकांश लोग क्या खोज रहे थे। – rolls

1

अगर मैं अपने प्रश्न समझ में आप इस तरह कुछ करना चाहता हूँ:

Exception ex = new Exception("test"); 
Exception innerEx = new Exception("inner"); 
ex.GetType().GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(ex, innerEx); 

आप एक वस्तु है कि अपवाद से विरासत के निर्माता में हैं, तो आप पहली बार ex के बजाय this का प्रयोग करेंगे।

लेकिन यह संभालने का प्रयास करने वाले किसी भी चीज़ को संभालने का सबसे अच्छा तरीका नहीं हो सकता है।

+0

अपवाद आंतरिकEx = नया अपवाद ("आंतरिक") के साथ क्या गलत है; अपवाद पूर्व = नया अपवाद ("परीक्षण", आंतरिकEx); ? –

+0

वह उस ऑब्जेक्ट को संशोधित करने का प्रयास कर रहा है जो संदर्भ में नहीं बनाया गया था, मैं इसे केवल डेमोइंग के उद्देश्य के लिए बना देता हूं। दरअसल अपने मामले में वह इस उदाहरण को संशोधित करने की कोशिश कर रहा है। – pauloya

+0

+1: इसने अपने स्वयं के मूर्खतापूर्ण प्रश्न का उत्तर दिया कि अपवाद के आंतरिक अपवाद को कैसे मजबूर किया जाए, इस प्रकार मज़ेदार चीजें पैदा करने जैसे टॉस्ट्रिंग() विधि एक स्टैक ओवरफ़्लो को ट्रिगर करती है। – Brian

1

फ़ील्ड खोजने के लिए रेडगेट के परावर्तक का उपयोग करें। मुझे संदेह है कि अपवाद कार्यान्वयन कभी भी बदल जाएगा ... लेकिन यह एक जोखिम है!

+0

आप इस पर शक क्यों करेंगे? इस मूल्यांकन के लिए आपके पास क्या आधार है? अगर मैं माइक्रोसॉफ्ट था, तो मैं केवल उन लोगों को उत्तेजित करने के लिए कार्यान्वयन को बदल दूंगा जो अन्य लोगों के वर्गों के आंतरिक कार्यान्वयन विवरण पर निर्भर करते हैं। –

+2

पिछले ढांचे के अपडेट में बदलाव किए गए ऐसे विवरणों की राशि के आधार पर? –

+1

@ जॉन: अच्छी बात यह है कि आप एमएस के लिए काम नहीं कर रहे हैं! – Scooterville

0

मुझे पता है कि मैं पार्टी के लिए वास्तव में देर से हूं, लेकिन मुझे लगता है कि यह काम करता है।

public class MyException: Exception 
{ 
    public void SetInnerException(Exception exception) 
    { 
     typeof(Exception) 
      .GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance) 
      .SetValue(this, exception); 
    } 
} 

चाल वास्तविक Exception प्रकार के _innerException क्षेत्र मिलता है, और फिर अपने वर्ग उदाहरण (इस मामले में MyException) के लिए भीतरी अपवाद मान सेट करने के लिए है।

यह चर के लिए भी काम करता है।

Exception mainException = new Exception(); 
typeof(Exception) 
    .GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance) 
    .SetValue(mainException , new Exception("Something bad happened!")); 
संबंधित मुद्दे