2008-08-11 11 views
6

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

  • संग्रह में सभी आइटम के माध्यम से पाशन देखें कि उनमें से एक है आप के लिए क्या देख रहे द्वारा अपने स्वयं के Contains() विधि को लागू करें। यह "सर्वोत्तम अभ्यास" दृष्टिकोण प्रतीत होता है।
  • मैं हाल ही में कुछ कोड जहां एक पाश के बजाय, वहाँ एक कोशिश बयान के अंदर वस्तु का उपयोग करने का प्रयास किया गया में आए इस प्रकार है:
try 
{ 
    Object aObject = myCollection[myObject]; 
} 
catch(Exception e) 
{ 
    //if this is thrown, then the object doesn't exist in the collection 
} 

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

उत्तर

2

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

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

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

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

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

ये कब और पर अच्छा लेख के एक जोड़े जहां यह आम तौर पर अपवाद फेंकने के लिए स्वीकार्य माना जाता है कर रहे हैं :

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

0

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

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

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

-2

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

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

0

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

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

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

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

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

0

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

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

4

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

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

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

1

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

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

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

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

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

के लिए क्यों अपवाद असाधारण होना चाहिए के रूप में, इसके बारे में 2 बातें

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

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

0

Krzystof को इस ब्लॉग पोस्ट पर एक नज़र डालें: http://blogs.msdn.com/kcwalina/archive/2008/07/17/ExceptionalError.aspx

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

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

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