2011-08-08 18 views
6

बात यह है कि वास्तव में मुझे सबसे कुछ प्रोग्रामिंग भाषाओं (जैसे सी #, जावास्क्रिप्ट) के बारे में परेशान करती है कि null की संपत्ति का उपयोग करने की कोशिश कर रहा है का कारण बनता है एक त्रुटि या अपवाद होने के लिये है।क्यों नल की संपत्ति तक पहुंचने का प्रयास कुछ भाषाओं में अपवाद का कारण बनता है?

उदाहरण के लिए, निम्नलिखित कोड का टुकड़ा में,

foo = bar.baz; 

अगर बार null है, सी # एक बुरा NullReferenceException और मेरे जावास्क्रिप्ट दुभाषिया Unable to get value of the property 'baz': object is null or undefined साथ शिकायत फेंक देते हैं।

मैं की तरह

foo.bar.baz.qux 

सिद्धांत रूप में इस बात को समझ सकते हैं, लेकिन असली कोड में मैं अक्सर कुछ हद तक गहरी वस्तुओं है, और अगर बीच foo, bar, या baz किसी भी रिक्त है, मेरे कोड टूट रहे हैं। ।

true.toString() //evaluates to "true" 
false.toString() //evaluates to "false" 
null.toString() //should evaluate to "null", but interpreter spits in your face instead 

मैं बिल्कुल इस समस्या को संभालने के लिए, हमेशा वर्बोज़ है, क्योंकि यह लेखन कोड घृणा, बदबूदार कोड: :(इसके अलावा, अगर मैं एक कंसोल में निम्न भाव का मूल्यांकन, वहाँ असंगत परिणाम होने लगते हैं

if (!(solvedPuzzles && 
     solvedPuzzles[difficulty] && 
     solvedPuzzles[difficulty][index])) { 
     return undefined; 
    } 
return solvedPuzzles[difficulty][index].star 

और

if (context != null && 
    context.Request != null && 
    context.Request.Cookies != null && 
    context.Request.Cookies["SessionID"] != null) 
{ 
    SessionID = context.Request.Cookies["SessionID"].Value; 
} 
else 
{ 
    SessionID = null; 
} 
: निम्न काल्पनिक नहीं उदाहरण हैं, मैं अपनी परियोजनाओं में से एक (प्रथम, जावास्क्रिप्ट में है दूसरा सी # में है) से इन पकड़ा अगर पूरी अभिव्यक्ति null लौटे, तो गुण में से किसी एक अशक्त था

हालात इतना आसान नहीं होगा। उपर्युक्त कोड उदाहरण इतने सरल हो सकते थे:

return solvedPuzzles[difficulty][index].star; 
    //Will return null if solvedPuzzles, difficulty, index, or star is null. 

SessionID = context.Request.Cookies["SessionID"].Value; 
    //SessionID will be null if the context, Request, Cookies, 
    //Cookies["SessionID"], or Value is null. 

क्या मुझे कुछ याद आ रही है? क्यों इन भाषाओं इस व्यवहार के बजाय का उपयोग नहीं करते? क्या किसी कारण से इसे लागू करना मुश्किल है? क्या यह उन समस्याओं का कारण बनता है जिन्हें मैं देख रहा हूं?

+0

श्रृंखला में उन सभी मूल्यों के लिए शून्य मान मान्य है? पहली जगह में नल स्टोर करना आसान नहीं है। फिर आप उन चेकों से पूरी तरह से बच सकते हैं। –

+1

आप [नल ऑब्जेक्ट पैटर्न] (http://en.wikipedia.org/wiki/Null_Object_pattern) से प्यार करेंगे ... – fredoverflow

+3

यह भाषा की गलती नहीं है जिसे आपने खाली संग्रह के बजाय शून्य संग्रह करने का निर्णय लिया है .. – canon

उत्तर

8

यह समस्या है कि मैं अनदेखी कर रहा हूँ कारण हैं?

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

कुछ भाषाओं (जैसे ग्रूवी के रूप में) एक अशक्त-सुरक्षित भिन्नता ऑपरेटर जो मदद कर सकते हैं प्रदान करते हैं। सी # में यह कुछ ऐसा दिखाई दे सकता है:

SessionID = context?.Request?.Cookies?["SessionID"]?.Value; 

मेरा मानना ​​है कि सी # टीम अतीत में इस पर विचार किया और यह समस्याग्रस्त पाया है, लेकिन इसका मतलब यह नहीं है कि वे निश्चित रूप से भविष्य में फिर से मिलना नहीं होगा यह ।

2

और फिर यदि उस का पूंछ अंत उस विधि को कॉल करता है जो बूल लौटाता है, तो क्या? Main.Child.Grandchild.IsEdit() और bool IsEdit();

मुझे लगता है कि यह एक "अशक्त" उदाहरण है कि डिफ़ॉल्ट व्यवहार रिटर्न (इस the null object pattern के रूप में जाना जाता है) के लिए बेहतर होगा।

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

आप INull से सभी "अशक्त" वस्तुओं प्राप्त कर सकता है, उन्हें अपने वर्ग के नाम के खिलाफ एक हैश में डाल दिया है, तो उस का उल्लेख करता है, तो एक सदस्य के रिक्त है। फिर आप डिफ़ॉल्ट "शून्य" कार्यान्वयन को नियंत्रित कर सकते हैं (यदि ऑब्जेक्ट "शून्य" है तो 0 स्वीकार्य होगा)

इसके अलावा, "शून्य" ऑब्जेक्ट्स को एक्सेस किए जाने पर अपवाद फेंक सकते हैं, इस तरह आप जानते हैं कि आपने एक तक पहुंचा है, और चुनें कि यह कब ठीक होगा। तो आप अपना खुद का "शून्य ऑब्जेक्ट अपवाद" कार्यान्वित कर सकते हैं।

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

+0

देखें ... इसे 'बूल बनाएं? IsEdit() ': पी –

+0

मुझे नहीं पता कि यह सबसे अच्छा है क्योंकि मुझे नहीं लगता कि आपके पास एक ही नियंत्रण होगा। –

+0

यह निश्चित रूप से बेहतर नहीं है। मैं मज़ाक कर रहा था। –

1

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

+0

मुझे इस से सहमत होना है- आपके इनवेरिएंट पर्याप्त मजबूत नहीं हैं। – Puppy

0

सामान्य रूप में foo.Baz का अर्थ है "उदाहरण पर अगर foo, baz सदस्य निष्पादित करें"। यह गतिशील भाषा, आभासी सदस्य या कुछ भी हो सकता है - लेकिन हम आधार पर पहले चरण में विफल रहे हैं: कोई उदाहरण नहीं है।

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

इसी प्रकार, मैं असहमत हूं कि null.toString() को "शून्य" वापस करना चाहिए - आईएमओ यह असफल होने के लिए यह सामान्य है। "सामान्य" के रूप में शून्य पर पहुंच का इलाज स्वाभाविक रूप से गलत IMO है।

+0

इकाइयों या परिवर्तनीय डेटा धारकों का प्रतिनिधित्व करने वाले प्रकारों के लिए, 'शून्य' पर संचालन वास्तव में समझ में नहीं आता है। अपरिवर्तनीय संदर्भ प्रकारों के लिए, हालांकि, एकमात्र चीज जो "गलत" होगी, जिससे प्रकारों को 'डिफ़ॉल्ट (कुछ ImmutableRefType) बनाने की इजाजत मिलती है। कुछ यादगार()' कुछ उपयोगी करते हैं, यह तथ्य होगा कि 'Nullable 'पर' struct' बाधा इसका मतलब है कि उस प्रकार के एक सुस्त समकक्ष को परिभाषित करने के लिए कोई "मानक" तरीका नहीं होगा। अन्यथा मुझे कोई कारण नहीं दिखता कि एक अपरिवर्तनीय संदर्भ प्रकार एक मूल्यवान डिफ़ॉल्ट मान सहित मूल्य प्रकार की तरह काम करने में सक्षम नहीं होना चाहिए। – supercat

0

वहाँ कुछ मैं याद कर रहा हूँ है? ये भाषाएं इस व्यवहार का उपयोग क्यों नहीं करतीं? क्या किसी कारण से इसे लागू करना मुश्किल है? क्या यह समस्याएं पैदा कर सकता है?

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

विकल्प नल पॉइंटर समस्या और कार्यक्रम एक और पंक्ति चल पाएंगे छिपाने के लिए होगा, लेकिन शायद बाद में या और भी बदतर क्रैश गलत उत्पादन का कारण!

इसके अलावा जब एक बग को ठीक करने की कोशिश कर रहा है, यह जिस तरह से यह तय करने के लिए आसान है अगर यह एक NullReferenceException सही फेंक देता है और डीबगर आप लाइन को देख शुरू करने के लिए पता चलता है। विकल्प अस्पष्ट लक्षण होंगे - डीबग करना बहुत मुश्किल है!

यह बहुत null साथ कार्यक्रम जब तुम नहीं करना चाहिए आम है।आपकी उपरोक्त परीक्षाओं में nullमाध्य क्या है। जवाब यह है कि इसका मतलब कुछ भी नहीं है। कोड के पाठक के रूप में मैं मानता हूं कि लेखक कुछ भूल गया था।

आमतौर पर सबसे अच्छा समाधान क्या है, जिसे मैं कहता हूं, "शून्य ऑब्जेक्ट" जिसे null के बजाय वापस किया जा सकता है। आपके उदाहरण में संभवतया अंत में बाद में परिणाम प्राप्त करने के लिए "नोडिफ्फ्सी" या "अज्ञात डिफिक्की" कक्षा वापस की जा सकती है - क्लीन कोड।

+0

ईमानदारी से 'NullReferenceException' अस्पष्ट लक्षण से बहुत दूर नहीं है, क्योंकि' x = null' पंक्ति 'y.foo()' पंक्ति से सैकड़ों मील दूर हो सकती है जो फेंकता है। –

+0

हाँ, यह है। मेरा विश्वास करो, मैंने दोनों की कोशिश की है। :) – vidstige

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