"ऑब्जेक्ट रेफरेंस ऑब्जेक्ट के इंस्टेंस पर सेट क्यों नहीं होता" हमें बताएं कि कौन सी ऑब्जेक्ट है?


39

हम एक प्रणाली शुरू कर रहे हैं, और हम कभी-कभी NullReferenceExceptionसंदेश के साथ प्रसिद्ध अपवाद प्राप्त करते हैं Object reference not set to an instance of an object

हालांकि, एक ऐसी विधि में जहां हमारे पास लगभग 20 ऑब्जेक्ट हैं, जिसमें एक लॉग होता है जो कहता है कि एक वस्तु अशक्त है, वास्तव में इसका कोई फायदा नहीं है। यह आपको बताने जैसा है, जब आप एक सेमिनार के सुरक्षा एजेंट होते हैं, कि 100 उपस्थित लोगों में से एक आतंकवादी है। यह वास्तव में आप के लिए कोई फायदा नहीं है। आपको अधिक जानकारी प्राप्त करनी चाहिए, यदि आप यह पता लगाना चाहते हैं कि धमकी देने वाला आदमी कौन सा है।

इसी तरह, यदि हम बग को हटाना चाहते हैं, तो हमें यह जानना होगा कि कौन सी वस्तु अशक्त है।

अब, कुछ ने कई महीनों तक मेरे मन को मोह लिया है, और वह है:

.NET हमें नाम क्यों नहीं देता, या कम से कम वस्तु संदर्भ का प्रकार, जो शून्य है? । क्या यह प्रतिबिंब या किसी अन्य स्रोत से प्रकार को नहीं समझ सकता है?

साथ ही, यह समझने के लिए कि कौन सी वस्तु अशक्त है, सबसे अच्छा अभ्यास क्या है? क्या हमें हमेशा इन संदर्भों में वस्तुओं की अशक्तता को मैन्युअल रूप से जांचना चाहिए और परिणाम को लॉग इन करना चाहिए? क्या कोई बेहतर तरीका है?

अद्यतन: अपवाद The system cannot find the file specifiedमें एक ही प्रकृति है। जब तक आप प्रक्रिया और डीबग से जुड़ नहीं जाते, तब तक आप कौन सी फ़ाइल नहीं ढूंढ सकते। मुझे लगता है कि इस प्रकार के अपवाद अधिक बुद्धिमान हो सकते हैं। क्या यह बेहतर नहीं होगा यदि .NET हमें c:\temp.txt doesn't exist.उस सामान्य संदेश के बजाय बता सके ? एक डेवलपर के रूप में, मैं हाँ वोट देता हूं।


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

2
इसके अलावा, मैंने हमेशा सोचा है कि विज़ुअल स्टूडियो में अपवाद सहायक संवाद में newक्लास के उदाहरण बनाने के लिए "सहायक" संकेत शामिल हैं । इस तरह के संकेत हर वास्तव में कब मदद करते हैं?
पर्सनल

1
यदि आपके पास दस ऑब्जेक्ट कॉल की एक श्रृंखला है, तो आपको अपने डिज़ाइन में युग्मन के साथ समस्या है।
पीट किर्कम

4
इस सवाल को देखें stackoverflow.com/questions/14787580/…

9
मुझे पसंद है कि इस सवाल का हर एक जवाब "एक डिबगर का उपयोग करें, अपनी त्रुटियों को लॉग इन करें, अशक्त के लिए जाँच करें, यह वैसे भी आपकी गलती है" की तर्ज पर है, जो इस प्रश्न का उत्तर नहीं दे रहे हैं लेकिन दोष आप पर डाल रहे हैं। केवल स्टैकओवरफ़्लो पर ही कोई आपको वास्तव में उत्तर देता है (जो मुझे लगता है कि यह वीएम के लिए बहुत अधिक उपरीकरण है)। लेकिन वास्तव में, केवल वे लोग जो इस प्रश्न का ठीक से उत्तर दे सकते हैं, वे Microsoft से हैं जिन्होंने रूपरेखा पर काम किया है।
रॉकलैन

जवाबों:


28

NullReferenceExceptionमूल रूप से आपको बताता है: आप इसे गलत कर रहे हैं। न कुछ ज्यादा, न कुछ कम। यह एक पूर्ण-डिबगिंग उपकरण नहीं है, इसके विपरीत। इस मामले में मैं कहूंगा कि आप इसे गलत कर रहे हैं क्योंकि दोनों

  • एक NullReferenceException है
  • आपने इसे इस तरह से नहीं रोका कि आप जानते हैं कि ऐसा क्यों / कहाँ हुआ
  • और यह भी हो सकता है: 20 वस्तुओं की आवश्यकता वाली एक विधि थोड़ी दूर लगती है

चीजों के गलत होने, और डेवलपर को अच्छी जानकारी प्रदान करने से पहले मैं सब कुछ जांचने का बहुत बड़ा प्रशंसक हूं। संक्षेप में: चेक का उपयोग ArgumentNullExceptionऔर पसंद लिखें और नाम स्वयं लिखें। यहाँ एक नमूना है:

void Method(string a, SomeObject b)
{
    if (a == null) throw ArgumentNullException("a");
    if (b == null) throw ArgumentNullException("b");

    // See how nice this is, and what peace of mind this provides? As long as
    // nothing modifies a or b you can use them here and be 100% sure they're not
    // null. Should they be when entering the method, at least you know which one
    // is null.
    var c = FetchSomeObject();
    if(c == null)
    {
        throw InvalidOperationException("Fetching B failed!!");
    }

    // etc.
}

आप कॉन्ट्रैक्ट कॉन्ट्रैक्ट में भी देख सकते हैं , इसमें क्वर्की है लेकिन यह बहुत अच्छी तरह से काम करता है और आपको कुछ टाइपिंग बचाता है।


17
@SaeedNeamati आप यह नहीं मान रहे हैं कि आपके पास एक बड़ा कोडबेस होने के कारण आपको सभ्य त्रुटि जाँच नहीं करनी चाहिए, है ना? इमो जितना बड़ा प्रोजेक्ट है, उतनी ही महत्वपूर्ण भूमिका या त्रुटि की जाँच और रिपोर्टिंग है।
१२:५२

6
अच्छी सलाह के लिए +1, भले ही वह वास्तविक प्रश्न का उत्तर न दे (जो शायद केवल एंडर्स हेजलबर्ग ही उत्तर दे सकते हैं)।
रॉस पैटरसन

12
उत्कृष्ट सलाह के लिए +1। @SaeedNeamati आपको इस सलाह को सुनना चाहिए। आपकी समस्या लापरवाही और कोड में व्यावसायिकता की कमी के कारण है। यदि आपके पास अच्छा कोड लिखने का समय नहीं है, तो आपको बहुत बड़ी समस्याएँ हैं ...
MattDavey

3
यदि आपके पास अच्छा कोड लिखने का समय नहीं है , तो आपके पास निश्चित रूप से बुरा कोड लिखने का समय नहीं है । खराब कोड लिखने से अच्छा कोड लिखने में अधिक समय लगता है। जब तक आप वास्तव में बग की परवाह नहीं करते। और यदि आप वास्तव में बगों की परवाह नहीं करते हैं, तो प्रोग्राम को बिल्कुल क्यों लिखें?
MarkJ

5
@SaeedNeamati I only say that checking every object to get sure that it's not null, is not a good methodगंभीरता से। यह सबसे अच्छी विधि है। और सिर्फ अशक्त नहीं, उचित मूल्यों के लिए हर तर्क की जांच करें। पहले आप त्रुटियों को पकड़ते हैं, इसका कारण खोजने में आसान है। आप कॉल का पता लगाने के लिए स्टैक ट्रेस में कई स्तरों को पीछे नहीं करना चाहते हैं।
जिगौफ़िन

19

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

तो यह कितना उपयोगी होगा, उदाहरण के लिए, यदि आपको यह मिला ...

Object reference (HttpContext.Current) not set to instance of an object

...? कोड में जाने के लिए, इसके माध्यम से कदम बढ़ाएं, और यह काम करें कि आप जिस चीज़ को कॉल करने की कोशिश कर रहे हैं nullवह ठीक है, लेकिन क्यों न केवल हमें थोड़ी मदद करने के लिए हाथ दिया जाए?

मैं सहमत हूं कि आमतौर पर उत्तर प्राप्त करने के लिए कोड के माध्यम से कदम रखना उपयोगी होता है (क्योंकि आप शायद अधिक जानकारी प्राप्त करेंगे), लेकिन अक्सर NullReferenceExceptionपाठ और उदाहरण के ऊपर पाठ की तरह अधिक होने पर निराशा और समय की बचत होती ।

मैं तो बस कह रहा हूं।


रनटाइम को कैसे पता चलता है कि क्या अशक्त है?
विल

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

सहमत, और मैं KeyNotFoundExceptionकई अन्य
कष्टों के

असल में, नल डेरेफ्रेंसिंग के मामले में यह सीएलआर डेरेफेरेंस (ओपी के सवाल पर
शाहरुज जेफ्री


4

आपके लॉग में एक स्टैक ट्रेस शामिल होना चाहिए - जो आमतौर पर आपको संकेत देता है कि विधि में किस लाइन में समस्या है। आपको अपनी रिलीज़ बिल्ड बनाने की आवश्यकता हो सकती है, जिसमें पीडीबी प्रतीक शामिल हैं ताकि आपको पता चल सके कि त्रुटि किस लाइन पर है।

दी, यह इस मामले में आपकी मदद नहीं करेगा:

Foo.Bar.Baz.DoSomething()

बताई मत पूछो इस तरह के कोड से बचने के लिए सिद्धांत कर सकते हैं मदद करते हैं।

चूंकि जानकारी शामिल नहीं है, इसलिए मुझे यकीन नहीं है - मुझे संदेह है कि कम से कम डिबग बिल्ड में, यदि वे वास्तव में चाहते थे, तो वे इसका पता लगा सकते हैं। WinDBG में क्रैश डंप और खोलने से मदद मिल सकती है।


2

अपवादों को कॉल श्रृंखला तक असाधारण गैर-घातक स्थितियों को इंगित करने के लिए एक उपकरण के रूप में बनाया गया है । यही है, वे डिबगिंग टूल के रूप में डिज़ाइन नहीं किए गए हैं।

यदि कोई नल-पॉइंटर अपवाद डिबगिंग टूल था, तो यह डिबगर को सही स्थान पर इंगित करते हुए, डिबगर को कनेक्ट करने की अनुमति देते हुए, प्रोग्राम निष्पादन को मौके पर ही समाप्त कर देगा। इससे प्रोग्रामर को सभी संदर्भ जानकारी उपलब्ध होगी। (जो बहुत ज्यादा एक Segfault की वजह से एक शून्य सूचक का उपयोग सी में करता है, भले ही थोड़ा गंभीर रूप से हो।)

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

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


1

मुझे लगता है कि सिर पर नोक मारा, हालांकि स्पष्ट बिंदु यह भी है कि अगर आप एक मिल रहा है NullReferenceExceptionआप uninitialised चर है। यह तर्क कि आपके पास 20 ऑब्जेक्ट्स हैं जो एक विधि में पारित किए जा रहे हैं, इसे एक शमन नहीं कहा जा सकता है: जैसा कि कोड के एक रचयिता को आपको इसके कार्यों के लिए ज़िम्मेदार होना पड़ता है, जिसमें इसके कोडबेस के बाकी हिस्सों का अनुपालन शामिल है, जैसे कि चरों आदि का उचित और सही उपयोग।

यह शानदार, थकाऊ और कभी-कभी नीरस है, लेकिन अंत में मिलने वाले पुरस्कार इसके लायक हैं: कई बार ऐसा होता है जब मुझे कई गीगाबाइट में वजन करने वाली लॉग फाइलों से गुजरना पड़ता है, और वे लगभग हमेशा मददगार होती हैं। हालाँकि इससे पहले कि आप उस चरण में पहुंचें, डिबगर आपकी मदद कर सकता है, और उस चरण से पहले अच्छी योजना बहुत दर्द से बचाएगी (और मेरा मतलब यह नहीं है कि आपके लिए पूरी तरह से इंजीनियर कोड समाधान या तो: सरल रेखाचित्र और कुछ नोट्स और कर सकते हैं) कुछ नहीं से बेहतर हो)।

Object reference not set to an instance of an objectकोड के संबंध में हम उन मूल्यों पर अनुमान नहीं लगा सकते हैं जिन्हें हम पसंद कर सकते हैं: यह है कि प्रोग्रामर के रूप में हमारा काम है, और इसका सीधा सा मतलब है कि आपने एक अनधिकृत चर पास कर लिया है।


आपको एहसास है कि लोग विधानसभा भाषा में लिखने के लिए इस तरह के औचित्य की पेशकश करते थे? और स्वचालित कचरा संग्रह का उपयोग नहीं कर रहे हैं? और अंकगणित करने में सक्षम होने के नाते - हेक्स में? "शानदार, थकाऊ और कभी-कभी सुस्त" हम ऐसे कार्यों का वर्णन करते हैं जो स्वचालित होना चाहिए।
स्पाइक ० एक्सफ़ २

0

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

बस अपने कोड के माध्यम से कदम बढ़ाएं और देखें कि आपके सभी चर के मान कुछ बिंदुओं पर क्या हैं।

संपादित करें: स्पष्ट रूप से मैं हैरान हूं कि किसी और ने अभी तक डिबगर का उपयोग करने का उल्लेख नहीं किया है।


2
तो आप कह रहे हैं कि डिबगर का उपयोग करते समय सभी अपवादों को आसानी से पुन: पेश किया जा सकता है?
jgauffin

@jgauffin मैं कह रहा हूं कि आप डीबगर का उपयोग यह देखने के लिए कर सकते हैं कि सिंथेटिक यूनिट परीक्षणों के बजाय वास्तविक विश्व कोड में एक अपवाद क्यों फेंका जा रहा है जो वास्तव में कोड को पूरी तरह से परीक्षण नहीं कर सकता है या इकाई परीक्षण स्वयं बग हो सकता है जिसमें कारण हो सकते हैं उन्हें असली कोड में कीड़े याद आती है। एक डिबगर केवल किसी अन्य टूल के बारे में सोचता है, जिसे मैं (शायद वैग्रिंड या DTrace जैसी चीजों को छोड़कर) कर सकता हूं।
Cromulent

1
तो आप कह रहे हैं कि हमारे पास हमेशा असफल कंप्यूटर तक पहुंच है और यह डीबगिंग यूनिट परीक्षणों से बेहतर है?
jgauffin

@jgauffin मैं कह रहा हूं कि अगर आपके पास कोई विकल्प है तो अन्य टूल को वरीयता में डीबगर के साथ जाएं। बेशक अगर आपके पास वह विकल्प नहीं है तो यह एक गैर-स्टार्टर है। स्पष्ट रूप से इस सवाल के साथ ऐसा नहीं है, यही कारण है कि मैंने जो जवाब दिया वह मैंने दिया। यदि प्रश्न यह होता कि आप क्लाइंट कंप्यूटर पर इस समस्या को कैसे ठीक करते हैं, जिसमें दूरस्थ डिबगिंग (या स्थानीय डिबगिंग) करने का कोई तरीका नहीं है, तो मेरा जवाब अलग होता। आप उन तरीकों से मेरा जवाब देने की कोशिश कर रहे हैं, जिनके हाथ में सवाल की कोई प्रासंगिकता नहीं है।
Cromulent

0

यदि आप @ stijn के उत्तर के साथ जाना चाहते हैं और अपने कोड में अशक्त चेक डालते हैं, तो इस कोड स्निपेट की मदद करनी चाहिए। यहाँ कोड स्निपेट्स के बारे में कुछ जानकारी दी गई है । एक बार जब आप यह सेट कर लेते हैं, तो बस टाइप करें argnull, दो बार टैब हिट करें, और फिर रिक्त स्थान भरें।

<CodeSnippet Format="1.0.0">
  <Header>
    <Title>EnsureArgNotNull</Title>
    <Shortcut>argnull</Shortcut>
  </Header>
  <Snippet>
    <Declarations>
      <Literal>
        <ID>argument</ID>
        <ToolTip>The name of the argument that shouldn't be null</ToolTip>
        <Default>arg</Default>
      </Literal>
    </Declarations>
    <Code Language="CSharp">
      <![CDATA[if ($argument$ == null) throw new ArgumentNullException("$argument$");$end$]]>
    </Code>
  </Snippet>
</CodeSnippet>

नोट: c # 6 में अब nameofआपका स्निपेट हो सकता throw new ArgumentNullException(nameof($argument$))है, जिसमें जादू स्थिरांक न होने के फायदे हैं, जिसे कंपाइलर द्वारा जांचा जा रहा है, और
रिफ्लेक्टरिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.