2009-02-23 11 views
11

ऐसा लगता है कि मेरे कई डिबगिंग समय जटिल वक्तव्यों में शून्य संदर्भ संदर्भ अपनाने का पीछा करते हैं। उदाहरण के लिए:एक नल-रेफरेंस अपवाद उस ऑब्जेक्ट का नाम क्यों नहीं दे सकता है जिसमें शून्य संदर्भ है?

For Each game As IHomeGame in _GamesToOpen.GetIterator() 

क्यों, जब मैं एक NullReferenceException मिलता है, मैं स्टैक ट्रेस में पंक्ति संख्या, लेकिन नहीं उद्देश्य यह है कि अशक्त के बराबर होती है के नाम पर प्राप्त कर सकते हैं।

Object reference not set to an instance of an object. 
बजाय

_GamesToOpen is not set to an instance of an object. 

या

Anonymous object returned by _GamesToOpen.GetIterator() is null. 

या

game was set to null. 

इस सख्ती से एक डिजाइन पसंद है, गुमनामी को सुरक्षित करने हेतु: दूसरे शब्दों में, क्यों में कोड का या एक कंप है कंपाइलर डिज़ाइन में इलिंग कारण कारण यह जानकारी डीबग-टाइम अपवाद में शामिल नहीं है?

उत्तर

11

अपवाद रनटाइम चीजें हैं, चर समय संकलित कर रहे हैं।

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

Dim a as New MyObject 
Dim b as String = MyObject.GetNullValue().ToString() 

क्या त्रुटि संदेश क्रम वापसी GetNullValue() विधि रिटर्न चाहिए अगर null: निम्न मान लें?

+2

रेखा संख्याएं भी रन-टाइम चीज हैं। डीबग-टाइम संकलन में सभी प्रकार की संकलन-समय चीजें होती हैं (कक्षा और विधि नाम, रेखा संख्या, आदि) परिवर्तनीय नाम क्यों नहीं? –

+1

कक्षाओं और विधियों और पैरामीटर नाम वास्तव में आईएल स्तर पर मौजूद हैं। लेकिन उत्पन्न आईएल में चर बहुत अधिक चले गए हैं। असल में, एक विशिष्ट चर के अपवाद से संबंधित कोई विशिष्ट तरीका नहीं है: मान लें "अगर (ए <बी) फेंक ...;" क्या समस्या "ए" या "बी" से संबंधित है? –

+0

उपर्युक्त टिप्पणी के कारण स्वीकृत। –

1

किसी ऑब्जेक्ट का उपयोग करने से पहले एक आवेषण कथन रखने के लिए डिबगिंग के लिए इसे पकड़ने का एक आसान तरीका, शून्य के लिए जांचें और एक सार्थक संदेश आउटपुट करें।

+0

एक आवेषण के लिए यह संभव नहीं है। उदाहरण के लिए, आप एक लिंक अभिव्यक्ति के अंदर एक जोर नहीं जोड़ सकते हैं। –

+0

अगर मैं गलत हूं तो मुझे सही करें, लेकिन मैंने सोचा कि अनुकूलित बयान अनुकूलित रिलीज बिल्ड से हटा दिए गए हैं। – Marc

1

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

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

+0

यह ठीक है। आप शायद इसे रिलीज में नहीं चाहते हैं वैसे भी बनाता है। मैंने इस सवाल में निर्दिष्ट किया था कि मैं सोच रहा था कि आप डीबग बिल्ड में इसे क्यों नहीं देख सकते हैं। –

+0

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

1

योग्य कुछ बातें ...

1) जब आप अपना स्वयं का बना अपवाद यह ध्यान में रखना है (यदि आप नाराज हैं यह इसके लिए और ने इस कोई अगर आप कुछ और के लिए यह कर आप पर नाराज हो जाएगा)। यह देखते हुए कि अपवाद पथ को सामान्य पथ नहीं होना चाहिए, अपवाद बनाने में व्यतीत समय में उपयोगी जानकारी अच्छी तरह से योग्य है।

2) एक सामान्य प्रोग्रामिंग practive के रूप में इस शैली को अपनाने और आप अब तक कम मुद्दों होगा (हाँ अपने कोड लाइनों के मामले में लंबे समय तक हो जाएगा, लेकिन आप बहुत समय) की बचत होगी:

क) कभी नहीं एबी() सी(); x = a.b() करें; एक्स।सी(); (अलग-अलग लाइनों पर) इस तरह से आप एक शून्य के बारे में देख सकते हैं या अगर a.b() की वापसी शून्य है।

बी) पैरामीटर के रूप में एक विधि कॉल की वापसी कभी पास न करें - हमेशा चर को पास करें। एक (foo()); x = foo() होना चाहिए; एक (एक्स); यह डिबगिंग और मूल्य देखने में सक्षम होने के लिए अधिक है।

मुझे नहीं पता कि .NET और Java जैसे वातावरण रनटाइम का एक संस्करण प्रदान नहीं करते हैं, जिसमें इन प्रकार के अपवादों पर अधिक जानकारी होती है, जैसे इंडेक्स सीमा से बाहर सरणी पर था, नाम चर जब यह रिक्त है, आदि ... के

2

जावा जैसी भाषाओं के लिए कि बाईटकोड कि एक वीएम से व्याख्या हो जाता है करने के लिए संकलित किया गया है, तो आप एक क्षेत्र x के साथ एक कक्षा X है लगता है, और इसके मूल्य एक के लिए null है कुछ संदर्भ आप लिखते हैं तो

x.foo() 

बाईटकोड इस प्रकार दिखाई देंगे:

push Xref   >> top of stack is ref to instance of X with X.x = null 
getField x   >> pops Xref, pushes 'null' on the stack 
invokeMethod foo >> pops 'null' -> runtime exception 

मुद्दा यह है कि आपरेशन कि ढेर पर एक गैर-शून्य संदर्भ की जरूरत है उदाहरण में invokeMethod की तरह उस पर संचालित करने के लिए, है , यह नहीं पता और नहीं जानता कि उस नल संदर्भ कहां से आया था।

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

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