कंटेनर () के बजाय अनचाहे अपवादों का उपयोग करना?

कल्पना करें कि जिस ऑब्जेक्ट के साथ आप काम कर रहे हैं उसके साथ जुड़े अन्य ऑब्जेक्ट्स का संग्रह है, उदाहरण के लिए WinForm पर नियंत्रण संग्रह। आप संग्रह में किसी निश्चित वस्तु की जांच करना चाहते हैं, लेकिन संग्रह में शामिल है() विधि नहीं है। इससे निपटने के कई तरीके हैं।

  • संग्रह में सभी आइटमों के माध्यम से लूपिंग करके अपने स्वयं के () विधि को कार्यान्वित करें यह देखने के लिए कि उनमें से एक वह है जिसे आप ढूंढ रहे हैं। यह "सर्वोत्तम अभ्यास" दृष्टिकोण प्रतीत होता है।
  • मैं हाल ही में कुछ कोड में आया जहां लूप की बजाय, ऑब्जेक्ट को किसी कोशिश कथन के अंदर एक्सेस करने का प्रयास किया गया था:
  कोशिश
{
    ऑब्जेक्ट aObject = myCollection [myObject];
}
पकड़ो (अपवाद ई)
{
    // अगर इसे फेंक दिया जाता है, तो ऑब्जेक्ट संग्रह में मौजूद नहीं है
}
 

मेरा सवाल यह है कि प्रोग्रामिंग अभ्यास के खराब होने पर आप दूसरा विकल्प क्यों मानते हैं और क्यों? संग्रह के माध्यम से लूप की तुलना में इसका प्रदर्शन कैसा है?

0
ro fr bn

8 उत्तर

अंगूठे का सामान्य नियम नियंत्रण प्रवाह के लिए अपवादों का उपयोग करने से बचने के लिए है जब तक कि अपवाद को ट्रिगर करने वाली परिस्थितियां "असाधारण" नहीं हैं - उदाहरण के लिए, बेहद दुर्लभ!

यदि यह ऐसा कुछ है जो सामान्य रूप से और नियमित रूप से होता है तो इसे निश्चित रूप से अपवाद के रूप में नहीं संभाला जाना चाहिए।

सभी ओवरहेड शामिल होने के कारण अपवाद बहुत धीमे होते हैं, इसलिए प्रदर्शन के कारण भी हो सकते हैं, यदि यह अक्सर पर्याप्त होता जा रहा है।

0
जोड़ा

मुझे इसके बारे में और सोचना होगा कि मुझे यह कितना पसंद है ... मेरा आंत वृत्ति है, आह, इतना नहीं ...

संपादित करें: असाधारण मामले पर रयान फॉक्स की टिप्पणियां सही हैं, मैं सहमत हूं

प्रदर्शन के लिए, यह संग्रह पर सूचक पर निर्भर करता है। सी # आपको इंडेक्सर ऑपरेटर को ओवरराइड करने देता है, इसलिए यदि यह उस विधि के लिए लूप कर रहा है जिसमें आप लिखेंगे, तो यह उतना ही धीमा होगा (शायद कुछ नैनोसेकंड प्रयास/पकड़ के कारण धीमे हो ... लेकिन कुछ भी नहीं चिंता करें जब तक कि कोड स्वयं एक विशाल पाश के भीतर न हो)।

यदि सूचकांक ओ (1) (या यहां तक ​​कि ओ (लॉग (एन)) ... या ओ (एन) से कुछ भी तेज़ है), तो कोशिश/पकड़ समाधान निश्चित रूप से तेज़ होगा।

साथ ही, मुझे लगता है कि इंडेक्सर अपवाद फेंक रहा है, अगर यह शून्य हो रहा है, तो आप निश्चित रूप से केवल शून्य की जांच कर सकते हैं और कोशिश/पकड़ का उपयोग नहीं कर सकते हैं।

0
जोड़ा

अपवाद असाधारण होना चाहिए।

कुछ ऐसा है जैसे 'संग्रह गुम है क्योंकि डेटाबेस इसके नीचे से गिर गया है' असाधारण है

एक शब्दकोश के लिए 'कुंजी मौजूद नहीं है' जैसी कुछ सामान्य व्यवहार है।

Winforms नियंत्रण संग्रह के आपके विशिष्ट उदाहरण के लिए, नियंत्रण प्रॉपर्टी में ContainsKey विधि है, जो आप उपयोग करना चाहते हैं।

कोई ContainsValue नहीं है क्योंकि शब्दकोश/हैशटबेल से निपटने के दौरान, पूरे संग्रह के माध्यम से पुनरावृत्ति करने का कोई तेज़ तरीका नहीं है, यह जांचने के लिए कि कुछ मौजूद है या नहीं, तो आप वास्तव में ऐसा करने से निराश हैं।

चूंकि अपवाद असाधारण होना चाहिए, यह लगभग 2 चीजें हैं

  1. यह इंगित करना कि आपका कोड क्या करने का प्रयास कर रहा है। आप अपने कोड को मिलान करना चाहते हैं जो इसे प्राप्त करने की कोशिश कर रहा है, जितना संभव हो सके, इसलिए यह पठनीय और रखरखाव योग्य है। अपवाद हैंडलिंग अतिरिक्त क्रूर का एक गुच्छा जोड़ता है जो इस उद्देश्य के रास्ते में आता है

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

0
जोड़ा

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

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

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

0
जोड़ा

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

हालांकि, इस कोड के साथ मेरी मुख्य समस्या यह है कि अपवाद के प्रकार के बावजूद, आपको हमेशा एक ही परिणाम के साथ छोड़ा जा रहा है।

उदाहरण के लिए, एक अपवाद फेंक दिया जा सकता है क्योंकि ऑब्जेक्ट संग्रह में मौजूद नहीं है, या क्योंकि संग्रह स्वयं शून्य है या क्योंकि आप myOolject [myObject] को ऑब्जेक्ट पर नहीं डाल सकते हैं।

इन सभी अपवादों को उसी तरह से संभाला जाएगा, जो आपका इरादा नहीं हो सकता है।

ये अपवादों को फेंकने के लिए कब और कहाँ पर स्वीकार्य माना जाता है, इस पर कुछ अच्छे लेख हैं:

मैं विशेष रूप से दूसरे लेख से इस उद्धरण को पसंद करता हूं:

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

0
जोड़ा

उत्तरार्द्ध एक स्वीकार्य समाधान है। हालांकि मैं निश्चित रूप से विशिष्ट अपवाद (ElementNotFound?) पर पकड़ लेगा कि संग्रह उस मामले में फेंकता है।

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

0
जोड़ा

Take a look at this blog post from Krzystof: http://blogs.msdn.com/kcwalina/archive/2008/07/17/ExceptionalError.aspx

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

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

0
जोड़ा

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

अंतिम विचार के रूप में, इन दिनों अधिकांश संग्रह do में पहले से ही एक विधि है। तो मुझे लगता है कि अधिकांश भाग के लिए यह एक गैर-मुद्दा है।

0
जोड़ा