2012-04-12 26 views
5

में NullReferenceExceptions को संभालने के लिए मैं हाल ही में एक कोडिंग बग जहां कुछ विशेष परिस्थितियों में एक चर आरंभ नहीं किया जा रहा था था और मैं एक NullReferenceException हो रही थी। इसमें डीबग करने में थोड़ी देर लग गई क्योंकि मुझे डेटा के बिट्स मिलना पड़ा जो इसे उत्पन्न करने के लिए उत्पन्न करेगा क्योंकि अपवाद वैरिएबल नाम नहीं देता है।एक बेहतर तरीका सी #

जाहिर है मैं उपयोग करने से पहले हर चर की जांच कर सकता है और फेंक एक जानकारीपूर्ण अपवाद लेकिन वहाँ ऐसा करने का एक बेहतर (कम कोडिंग पढ़ें) तरीका है? एक और विचार मैंने pdb फ़ाइलों के साथ शिपिंग किया था ताकि त्रुटि जानकारी में कोड लाइन हो जो त्रुटि उत्पन्न करे। अन्य लोग इस समस्या से कैसे बचते हैं/हैंडल करते हैं?

धन्यवाद

+1

शून्य मूल्यों के लिए हमेशा उदारतापूर्वक 'जोर दें'। – leppie

+0

@leppie - यह बहुत ज़ोरदार है! हां, मैं ऐसा कर सकता था लेकिन मैं खाता परिस्थितियों को ध्यान में रखना एक और अधिक सुरुचिपूर्ण समाधान की उम्मीद कर रहा था जैसे कि मुझे ऐसा करना भूल जाता है :) –

+1

प्रोटिप: आपको विधियों को छोटा रखें (अधिकतम 10-20 लाइनें कहें), तो आपको वास्तव में लाइन नंबरों की आवश्यकता नहीं है । – leppie

उत्तर

11

सबसे पहले: एक ही बयान में बहुत ज्यादा काम नहीं है। यदि आपके पास एक पंक्ति में बड़ी संख्या में डेरफ्रेंसिंग ऑपरेशंस हैं, तो यह अपराधी को खोजने के लिए अधिक होगा। Law of Demeter इसके साथ भी मदद करता है - अगर आपके पास order.SalesClerk.Manager.Address.Street.Length जैसा कुछ है तो आपको अपवाद मिलने पर बहुत से विकल्प मिलेंगे। (मैं नहीं Demeter के कानून के बारे में लकीर का फकीर बना हूँ, लेकिन कम मात्रा में सब कुछ ...)

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

// What if foo is actually a Control, but we expect it to be String? 
string text = foo as string; 
// Several lines later 
int length = text.Length; // Bang! 

यहाँ हम एक NullReferenceException प्राप्त होता है और अंत में यह text करने के लिए वापस ट्रेस कर अशक्त जा रहा है - लेकिन फिर आप चाहे उसकी वजह foo अशक्त था पता नहीं होता, या क्योंकि यह एक अप्रत्याशित प्रकार था। यह सच में, सच एक string होना चाहिए, तो बजाय डाली:

string text = (string) foo; 

अब आप दो स्थितियों के बीच अंतर बताने में सक्षम हो जाएगा।

तीसरा: के रूप में अन्य लोगों ने कहा, अपने डेटा को मान्य - आम तौर पर सार्वजनिक और संभावित आंतरिक एपीआई के लिए तर्क। मैं Noda Time में पर्याप्त जगहों पर ऐसा करता हूं कि मुझे जांच अस्वीकार करने में मदद करने के लिए एक उपयोगिता वर्ग है। इसलिए उदाहरण (Period से) के लिए:

internal LocalInstant AddTo(LocalInstant localInstant, 
          CalendarSystem calendar, int scalar) 
{ 
    Preconditions.CheckNotNull(calendar, "calendar"); 
    ... 
} 

आप चाहिए दस्तावेज़ क्या कर सकते हैं और, नल नहीं हो सकता भी।

+0

हाँ, ये अच्छी युक्तियां हैं। क्या मुझे पीडीबी फाइलों के साथ शिपिंग करना चाहिए ताकि लाइन दी जा सके? वर्तमान में मेरा उत्पादन कोड विधि का नाम प्रदान करता है लेकिन रेखा नहीं जो कठिनाई को जोड़ती है। –

+0

'प्रत्येक पंक्ति पर ज्यादा न करें' के साथ आप 'प्रत्येक विधि में बहुत अधिक न करें' जोड़ सकते हैं। इससे समस्या को कम करने में मदद मिलती है। – Servy

+0

@ डायरेक्टेडबिट: यह आपकी स्थिति पर निर्भर करता है ... सर्वर-साइड कोड के लिए, बिल्कुल। यदि आप क्लाइंट-साइड कोड शिपिंग कर रहे हैं, तो * * अधिक संवेदनशील या गन्दा हो सकता है ... –

2

यह कहने के लिए खेद है कि मैं हमेशा यह सत्यापित करने के लिए एक जांच करूँगा कि किसी विशेष वस्तु में मैं जिस वस्तु का उपयोग कर रहा हूं वह शून्य नहीं है।

यह रूप में सरल रूप में

if(this.SubObject == null) 
{ 
    throw new Exception("Could not perform METHOD - SubObject is null."); 
} 
else 
{ 
... 
} 

अन्यथा मैं किसी भी तरह की सोच भी नहीं सकते गहन रूप से है। मुझे यह समझ में नहीं आता कि इन जांचों को वैसे भी न करें; मुझे लगता है कि यह सिर्फ अच्छा अभ्यास है।

+1

मुझे आशा है कि आप केवल अपवाद नहीं फेंक दें ... –

+0

हमेशा नहीं। मैं आमतौर पर अपवाद का विस्तार करता हूं। यह सिर्फ एक उदाहरण है। – DigitalJedi805

+2

इस मामले में आपको अमान्य ऑपरेशन अपवाद का उपयोग करना चाहिए यदि राज्य स्वयं मान्य है - और ArgumentNullException आपको उस स्थिति में आने से रोकने के लिए यदि यह नहीं है। –

2

सबसे पहले आपको हमेशा अपने इनपुट को सत्यापित करना चाहिए। यदि null की अनुमति नहीं है, तो ArgumentNullException फेंक दें।

अब, मुझे पता है कि यह है कि, दर्द हो सकता है तो आप विधानसभा उपकरण है कि वह आपके लिए क्या पुनर्लेखन पर गौर कर सकता है।विचार यह है कि आप किसी विशेषता का एक प्रकार है कि उन तर्कों null नहीं किया जा सकता को चिह्नित करना होगा होगा:

public void Method([NotNull] string name) { ... 

और rewriter रिक्त स्थान को भरने होगा ...

या एक सरल विस्तार विधि यह आसान

name.CheckNotNull(); 
+0

यह अच्छी सलाह है। दुर्भाग्य से यह सब मैं था। मैं फ़ंक्शन में एक ब्रैकेट को गलत स्थानांतरित कर दूंगा ताकि एक चर का उपयोग प्रारंभिकता के दायरे से बाहर किया जा सके। –

3

अपवाद के हर प्रकार है कि आपके आवेदन के निष्पादन के प्रवाह में कोई भी बिंदु पर हो सकता है के लिए मामलों का एक बहुत यह योजना असंभव और खाते के पास है में बना सकते हैं। रक्षात्मक कोडिंग केवल एक निश्चित बिंदु पर प्रभावी है। यह चाल आपके आवेदन में शामिल एक ठोस डायग्नोस्टिक स्टैक है जो आपको अनचाहे त्रुटियों और क्रैश के बारे में सार्थक जानकारी दे सकती है। ऐप-डोमेन स्तर पर एक अच्छा शीर्ष-स्तरीय (अंतिम खाई) हैंडलर होने से उसके साथ बहुत मदद मिलेगी।

हां, पीडीबी (यहां तक ​​कि एक रिलीज बिल्ड के साथ) शिपिंग एक पूर्ण स्टैक ट्रेस प्राप्त करने का एक अच्छा तरीका है जो सटीक स्थान और त्रुटियों के कारणों को इंगित कर सकता है। लेकिन जो भी डायग्नोस्टिक्स आप चुनते हैं, उसे आवेदन के डिजाइन में बेक किया जाना चाहिए (आदर्श)। मौजूदा ऐप को फिर से निकालना कठिन और समय/धन-गहन हो सकता है।

+0

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

+0

बात यह है कि यह विशेष विधि/स्थान पर निर्भर करता है ...कभी-कभी आप जो हुआ उसके बारे में विशिष्ट जानकारी चाहते हैं क्योंकि आप कुछ प्रकार की त्रुटियों की अपेक्षा कर सकते हैं। दूसरों में, जैसे मैंने कहा, आप शायद एक अप्रत्याशित स्थिति हो सकती है। सबसे पहले आप जो कर सकते हैं वह है 'AppDomain.UnhandledException' (या' ऐप_एरर' वेब ऐप के लिए global.asax में) को हुक करना, और उसके बाद आवश्यकतानुसार अलग-अलग तरीकों को फिर से शुरू करना प्रारंभ करना है। – kprobst

2

तुम सिर्फ अशक्त संदर्भ होने के खिलाफ कोड के लिए एक अधिक कॉम्पैक्ट रास्ता के लिए देख रहे हैं, अशक्त-कोलेसिंग ऑपरेटर ??MSDN

जाहिर की अनदेखी नहीं है, यह निर्भर करता है कि आप क्या कर रहे हैं, लेकिन यह करने के लिए इस्तेमाल किया जा सकता बयान के अतिरिक्त अतिरिक्त से बचें।

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