2011-12-31 16 views
17

मैं सवाल मिला: "क्या आप क्या करना चाहते हैं, अपवाद हैंडलिंग या यदि शर्त"अगर शर्त बनाम अपवाद संचालक

एक साक्षात्कार के लिए। मेरा जवाब यह था कि अपवाद हैंडलर केवल असाधारण परिस्थितियों के लिए पसंद करते हैं जैसे फ़ाइल लिखने पर डिस्क अनुमति त्रुटि। साक्षात्कारकर्ता कुछ अन्य जवाब की उम्मीद कर रहा था। सही जवाब क्या है?

संपादित करें: किसी भी विशिष्ट उदाहरण जहां अपवाद हैंडलिंग आमतौर पर इस्तेमाल किया जाता है जब किसी अगर-हालत और अधिक उपयुक्त हो गया होता?

+5

'साक्षात्कारकर्ता को कुछ अन्य उत्तर की उम्मीद लग रही थी' - तो आपने उससे क्यों नहीं पूछा? साक्षात्कार के दौरान मैं एक प्रश्न के मुकाबले एक प्रश्न से अधिक प्रभावित हूं ... –

उत्तर

23

जैसा कि इस प्रश्न को "सी #" टैग किया गया है, हम इन प्रकार के सवालों के जवाब देने के लिए .NET Framework Design दिशानिर्देशों को एक अच्छे प्रारंभिक बिंदु के रूप में देख सकते हैं। यह एमएसडीएन पर "Exception Throwing" के तहत दिया गया मार्गदर्शन है:

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

यहाँ एक बुरा अभ्यास जहां एक अपवाद नियंत्रित किया जाता है, लेकिन लगभग हमेशा से बचा जा सकता का एक उदाहरण है:

public int? GetItem(int index) 
{ 
    int? value = null; 
    try 
    { 
     value = this.array[index]; 
    } 
    catch (IndexOutOfRangeException) 
    { 
    } 

    return value; 
} 

यह काल्पनिक लगता है, लेकिन मैं नए प्रोग्रामर से अक्सर इस तरह कोड देखें। array पर पढ़ने और लिखने के आसपास उचित सिंक्रनाइज़ेशन मानते हुए, यह अपवाद 100% निश्चित रूप से टाला जा सकता है। यह देखते हुए कि, एक बेहतर तरीका है कि कोड लिखने के लिए निम्न होगा:

public int? GetItem(int index) 
{ 
    int? value = null; 

    // Ensure the index is within range in the first place! 
    if (index >= 0 && index < this.array.Length) 
    { 
     value = this.array[index]; 
    } 

    return value; 
} 

अन्य मामलों जहां यथोचित अपवाद से बचने नहीं कर सकते हैं और उन्हें संभाल करने की आवश्यकता है। यह आमतौर पर तब सामना किया जाता है जब आपको बाहरी संसाधनों जैसे कि फाइल या नेटवर्क कनेक्शन से निपटना होता है, जिन्हें आप किसी भी समय पहुंच या संपर्क में संभावित रूप से खो सकते हैं। WCF से उदाहरण:

public void Close() 
{ 
    // Attempt to avoid exception by doing initial state check 
    if (this.channel.State == CommunicationState.Opened) 
    { 
     try 
     { 
      // Now we must do a (potentially) remote call; 
      // this could always throw. 
      this.channel.Close(); 
     } 
     catch (CommunicationException) 
     { 
     } 
     catch (TimeoutException) 
     { 
     } 
    } 

    // If Close failed, we might need to do final cleanup here. 
    if (this.channel.State == CommunicationState.Faulted) 
    { 
     // local cleanup -- never throws (aside from catastrophic situations) 
     this.channel.Abort(); 
    } 
} 

यहां तक ​​कि ऊपर के उदाहरण में, यह आपरेशन आप क्या करने जा रहे कम से कम एक मौका सफल होने की है कि जाँच करने के लिए अच्छा है। तो अभी भी एक if() चेक है, उसके बाद उचित अपवाद हैंडलिंग तर्क के बाद।

+0

अपने 'गेटइटम' उदाहरण में, कॉलर यह निर्धारित करने में असमर्थ है कि एक अवैध 'इंडेक्स' की आपूर्ति की गई थी, या यदि 'सरणी [अनुक्रमणिका]' में 'शून्य' मान है। तो सवाल यह है कि क्या बेहतर है। अगर आपको अमान्य अनुक्रमणिका का उपयोग किया गया तो क्या आपको अपवाद फेंकना चाहिए? या आप किसी भी संकेत के बिना एक 'शून्य' मान वापस कर देंगे कि एक त्रुटि हुई? किसी सरणी पर एक अमान्य अनुक्रमणिका का उपयोग करने से अपवाद भी होगा, यह सरणी प्रकार के डिफ़ॉल्ट मान को वापस नहीं करेगा! – comecme

+2

@comecme: उस उदाहरण में, आप मान सकते हैं कि 'सरणी' को 'int []' के रूप में घोषित किया गया था, इसलिए 'शून्य' का अर्थ केवल यह हो सकता है कि मान मौजूद नहीं है (बाहर या सीमा)। हां, कॉलर को पता नहीं चलेगा, लेकिन कार्यान्वयनकर्ता * अपवादों को नियंत्रण प्रवाह के रूप में उपयोग करेगा और नहीं करना चाहिए जो उदाहरण का बिंदु था। अपवाद फेंकने के बिना डिफ़ॉल्ट मान वापस करने के लिए मान्य है, हालांकि इस पैटर्न को आमतौर पर 'TryXxx' विधि में व्यक्त किया जाने की उम्मीद है, जैसा कि यहां चर्चा की गई है: http://msdn.microsoft।com/en-us/पुस्तकालय/ms229009.aspx – bobbymcr

10

अपवाद हैंडलिंग एक भारी और महंगा संचालन है जहां तक ​​प्रदर्शन का संबंध है। आप और है कि आवेदन के प्रदर्शन

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

और अंत के रूप में आप ने कहा कि अपवाद संचालन अनिश्चित स्थितियों के लिए किया जाना चाहिए या असाधारण मामलों के लिए यह डिफ़ॉल्ट विकल्प

संपादित

एक आम बुरा नहीं होना चाहिए अभ्यास मैं कुछ स्थानों पर देखा है इस

try 
{ 
    string str = "Some String" 
    int i = Convert.ToInt32(str); 
} 
catch (Exception ex) 
{ 
     MessageBox.Show("Invalid input");   
} 

अब अगर किसी और

012 का उपयोग करते हुए पकड़ आसानी से इस आवरण में बचा जा सकता है की कोशिश है
string str = "Some String" 
    int i; 
    if(!int.TryParse(str, out i)) 
    { 
     MessageBox.Show("Invalid input");   
    } 
+1

आम तौर पर स्ट्रिंग को परिवर्तित करने वाली कक्षा कक्षा संदेश प्रदर्शित करने वाले वर्ग नहीं होगी। यही कारण है कि अपवाद मौजूद हैं: उन्हें उच्च स्तर पर पकड़ लिया जा सकता है। – comecme

4

सही उत्तर केवल वह है जो आपने दिया था।

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

0

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

2

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

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

तो धारणात्मक:

  • अपरिभाषित परिणाम (प्लस अगर शर्त): कार्यक्रम को सफलतापूर्वक निर्धारित करता दिए गए इनपुट के लिए कोई वैध उत्पादन होता है।
  • अपवाद (प्लस ट्राई-कैच): प्रोग्राम इनपुट से संबंधित एप्लिकेशन में कुछ त्रुटि के कारण गणना पूर्ण नहीं कर सकता है।
संबंधित मुद्दे