2009-06-23 10 views
8

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

यदि मेरे पास कोई अपवाद है जो किसी तर्क की स्थिति का परीक्षण करने के बाद फेंक दिया जाता है, या मेरे पास एक अपवाद है जो परीक्षण के बाद फेंक दिया जाता है कि एक int उचित सीमा के भीतर है, तो मेरे अपवादों को ArgumentException और IndexOutOfRangeException प्राप्त करना चाहिए या क्या वे अपवाद का उत्तराधिकारी?

उत्तर

11

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

एक आईओएक्सप्शन के बारे में सोचें जिसमें अतिरिक्त जानकारी है, या ArgumentOutOfRangeException या ArgumentNullException के अलावा एक ArgumentException है।

2

मैं सिर्फ उत्सुक हूं, आप वास्तव में उन अपवादों का उपयोग क्यों नहीं करेंगे जो पहले से मौजूद हैं? ऐसा लगता है कि इन अपवादों की वही ज़रूरत है जो आपको चाहिए, आप उन लोगों का उपयोग करने के खिलाफ क्यों हैं?

+0

मैं केवल एक सामान्य सीमा से अधिक चीजों के लिए परीक्षण कर रहा हूं। उदाहरण के लिए tesitng अगर कोई तर्क किसी ऐसे राज्य में है जो दृढ़ता की अनुमति देता है। इस मामले में यह एक तर्क की जांच कर रहा है लेकिन रैली मैं ArgumentNotInPersitableState नामक एक और विशिष्ट अपवाद चाहता हूं या थॉस लाइन – Sruly

+0

के साथ कुछ विशेष मामले के लिए मैं सीधे अपवाद का वारिस करूंगा। –

+1

क्या आपके कॉलर्स आपके विशिष्ट अपवाद को पकड़ेंगे? यदि नहीं, तो आपको अपने अपवाद प्रकार की आवश्यकता नहीं है। बस अपना खुद का संदेश इस्तेमाल करें। –

2

व्यक्तिगत रूप से यदि मेरे पास इंडेक्सर है और इंडेक्स वैल्यू रेंज से बाहर है तो मैं केवल मौजूदा इंडेक्सऑटऑफेंजेंज अपवाद को फेंक दूंगा, मैं इससे विरासत में आने वाली परेशानी नहीं जाऊंगा।

यदि आप केवल इसी तरह के अपवादों के बारे में बात कर रहे हैं लेकिन बिल्कुल समान अपवाद नहीं हैं, तो ढांचे में प्रदान किए गए पैटर्न को देखें। ऐसा लगता है कि यह समझ में नहीं आता है, विरासत "एक-एक" संबंध का वर्णन करती है।

+0

मेरी टिप्पणी को BFree पर देखें। उस स्थिति में अपवाद एक ArgumentException है लेकिन यह थोड़ा और विशिष्ट है। – Sruly

+0

@ स्क्रू: उस मामले में मेरा दूसरा पैराग्राफ है, इसे मत करो। एप्लिकेशन अपवाद से प्रवेश करें और इसके साथ किया जाए। – AnthonyWJones

7

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

यह कहा गया है कि, मैंने पाया है कि, अधिकांश स्थितियों में, आप में सही शब्द का उपयोग करके अपवाद संदेश आम तौर पर एक नया अपवाद बनाने के लिए पर्याप्त होगा।

कैसे, उदाहरण के लिए throw new IntOutOfProperRangeException(); से throw new ArgumentOutOfRangeException("The int value was too large?");

+2

कभी-कभी यह जानना आवश्यक होता है कि बाहर से (बाहर से) जब वह int उचित सीमा से बाहर था। आप इसे कैसे देखेंगे? मुझे नहीं लगता कि एक अच्छा विचार यह पूछना है कि क्या अपवाद फेंक दिया गया है एक ArgumentOutOfRangeException अपवाद है और यदि संदेश "int मान बहुत बड़ा था" के बराबर है? इसके बजाए, मुझे लगता है कि यह करना बेहतर होगा: {...} पकड़ें (IntOutOfProperRangeException पूर्व) {// इसे संभाल लें}। बेशक, यह आपके आवेदन पर निर्भर करता है और आपको इसके साथ क्या करने की आवश्यकता है –

1

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

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

+0

वैसे भी आसानी से, आप अभी भी एक प्रकार की जांच और कास्ट कर सकते हैं ... (eww) –

+0

हां, और मैंने इसका उल्लेख नहीं किया क्योंकि मैं चाहता था अगर मैंने किया तो खुद को पंच करना होगा। –

0

लगभग हमेशा मुझे नहीं कुछ भी IOException, SQLException, अशक्त की तुलना में अधिक विशिष्ट के लिए IllegalArgumentException (nulls और/या बाहर के रेंज मान) और IllegalStateException का उपयोग करें ...

1

IMHO, वहाँ से इनहेरिट कोई समस्या नहीं है एक और अपवाद यह उस अपवाद के उद्देश्य को भी स्पष्ट करता है। लेकिन सुनिश्चित करें कि जो कुछ भी ParentException पर लागू होता है वह आपके द्वारा बनाए गए ChildException पर भी लागू होता है। अन्यथा, आप "Square extends Rectangle" problem के साथ समाप्त हो सकते हैं ...

+0

एक आयताकार स्क्वायर का विस्तार नहीं करेगा? या वह बात है? पहले उस वाक्यांश में भाग नहीं लिया है ... –

+0

@Monoxide: नहीं, स्क्वायर विस्तार (है-ए) आयताकार। जैसा कि मेरा "सभी वर्ग आयताकार हैं। सभी आयताकार वर्ग नहीं हैं" – AllenG

+0

प्वाइंट लिया गया। शायद यह रात का वह समय फिर से है ... –

0

यदि आप केवल सामान्य अपवाद का उपयोग करते हैं तो आप कभी भी अपने अपवाद के विशिष्ट अपवादों को फंसाने में सक्षम नहीं होंगे। यदि आप केवल

try 
{ 
} 
catch (Exception ex) 
{ 
} 

विशिष्ट त्रुटियों के लिए फ़िल्टर करने में सक्षम होने के बिना आप प्रत्येक अपवाद को पकड़ लेंगे।

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

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

यह मुझे उपयोगकर्ताओं को दस्तावेज़ करने की अनुमति देता है कि विधि कॉल एप्लिकेशन विशिष्ट अपवादों को फेंक देगा जिन्हें उन्हें संभालने की आवश्यकता है।

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

यहां मेरे पास एक उदाहरण है।

/// <summary> 
/// Drive error exception class. Thrown when a drive selection error has occured. 
/// </summary> 
[Serializable] 
public class DriveException : ApplicationException 
{ 
    /// <summary> 
    /// Default constructor. 
    /// </summary> 
    public DriveException() 
    { 
    } 
    /// <summary> 
    /// Constructor used with a message. 
    /// </summary> 
    /// <param name="message">String message of exception.</param> 
    public DriveException(string message) 
     : base(message) 
    { 
    } 
    /// <summary> 
    /// Constructor used with a message and an inner exception. 
    /// </summary> 
    /// <param name="message">String message of exception.</param> 
    /// <param name="inner">Reference to inner exception.</param> 
    public DriveException(string message, Exception inner) 
     : base(message, inner) 
    { 
    } 
    /// <summary> 
    /// Constructor used in serializing the data. 
    /// </summary> 
    /// <param name="info">Data stored to serialize/de-serialize</param> 
    /// <param name="context">Defines the source/destinantion of the straeam.</param> 
    public DriveException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 
} 
0

मुझे लगता है कि यह सब है कि क्या आप एक ArgumentOutOfRange के रूप में अपने ArgumentNotInPersitableState अपवाद को पकड़ने के लिए चाहते हैं पर निर्भर करता है। यदि ऐसा कैच ब्लॉक होगा (या यदि आप एक ढांचा लिख ​​रहे हैं, जो दूसरों द्वारा अनुमानित माना जाएगा) तो हाँ आपको प्रासंगिक अपवाद प्रकार का उत्तराधिकारी होना चाहिए।

3

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

इसके अलावा मुझे बेसबेस क्लास जैसे बेस एप्लिकेशन क्लास का उत्तराधिकारी होना है, और अपवाद/एस के लिए एक्सएमएल टिप्पणियां जोड़ना सुनिश्चित करें।

+0

+1 - रिफैक्टरिंग में सहायता के लिए अद्वितीय अपवाद बनाने के बारे में उत्कृष्ट बिंदु। – jpierson

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