2009-01-20 15 views
38

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

public static string ToInvariantString(this IFormattable value, string format) 
{ 
    return value.ToString(format, CultureInfo.InvariantCulture); 
} 

इस तरह अगर मान पैरामीटर रिक्त है एक NullReferenceException फेंक दिया जाएगा।

अन्य उदाहरण होगा:

public static string ToInvariantString(this IFormattable value, string format) 
{ 
    if (value == null) throw new ArgumentNullException("value"); 
    return value.ToString(format, CultureInfo.InvariantCulture); 
} 

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

किसी ने यह भी बताया कि एक NullReferenceException फेंकना गलत है, और हाँ, यह है। यही कारण है कि मैं इसे फेंक नहीं देता, मैं बस इसे होने देता हूं (सीएलआर इसे फेंक दें) विधि की रक्षा नहीं करके।

मुझे लगता है कि मैं ArgumentNullException (जो मैंने अभी तक उपयोग किया है) का पक्ष लेता हूं, लेकिन मुझे अभी भी लगता है कि NullReferenceException के खिलाफ बहस करने के लिए कम से कम कमरा है क्योंकि यह उन स्थानों पर अधिक प्राकृतिक लगता है जहां विधि जा रही है इस्तेमाल किया गया।

उत्तर

34

सामान्यतः, अपवादों में शामिल हैं, आपको एक विस्तार विधि का इलाज करना चाहिए जैसे कि यह एक सामान्य स्थैतिक विधि हो। इस मामले में आपको एक ArgumentNullException फेंकना चाहिए।

एक NullReferenceException यहाँ फेंकने कुछ कारणों

  • एक अशक्त संदर्भ वास्तव में ऐसा देखकर नहीं होती है एक counterintuitive
  • एक NullReferenceException फेंकने और होने के लिये एक NullReferenceException पैदा कर रहा है के लिए एक बुरा विचार है discernably अलग अपवाद का उत्पादन (अंतर देखने का एक तरीका त्रुटि कोड है)। सीएलआर द्वारा फेंकने वाले कई अपवादों के बारे में यह सच है।

When can you catch a StackOverflowException देखें (एक पोस्ट मैंने इस विषय पर किया था)।

  • एक विस्तार विधि को कॉल करने के लिए यह प्राथमिक रूप से कानूनी है जैसे कि यह एक नियमित विधि थी। उस स्थिति में मैं निश्चित रूप से NullReferenceException को छोड़कर नहीं, बल्कि इसके बजाय एक ArgumentNullException को छोड़ दूंगा।
+0

ग्रेट टिप्पणियां और जैसा कि मैंने पोस्ट के मेरे संपादन में उल्लेख किया है, यही कारण है कि मैं स्पष्ट रूप से NullReferenceException को फेंक नहीं देता, मैं अभी भी सीएलआर को फेंक देता हूं। –

+0

"वास्तव में एक शून्य संदर्भ नहीं हुआ"। हाँ इसने किया; आपने एक शून्य संदर्भ पारित किया और विधि ने इसे कम करने की कोशिश की। – piedar

+0

@piedar विधि ने इसे हटाने की कोशिश की, रनटाइम नहीं! –

1

उपयोगकर्ता के दृष्टिकोण से, विधि एक उदाहरण विधि की तरह दिखती है और कार्य करती है, इसलिए यदि मैं उन्हें था, तो मुझे एक NullReferenceException देखने की उम्मीद होगी।

यह कहा गया है कि, मैं आपके पहले उदाहरण में फेंकने के लिए बस "होने" के बजाय, कोड में स्पष्ट रूप से एक या दूसरे को फेंकने का सुझाव दूंगा।

+0

हां, मैंने स्पष्ट रूप से NullReferenceException को फेंकने का विचार किया है, लेकिन मेरी भावना यह है कि इसे वास्तव में संकलक के लिए आरक्षित किया जाना चाहिए, लेकिन आप बहुत सही हो सकते हैं। –

+2

किसी उपयोगकर्ता दृष्टिकोण से एक विस्तार विधि को एक्सटेंशन या स्थिर विधि दोनों के रूप में बुलाया जा सकता है। – JaredPar

1

ArgumentNullException। एक्सटेंशन विधियों को कॉल करने के लिए नहीं आवश्यकता है जैसे कि वे उदाहरण विधियां थीं। आप उन्हें कॉल कर सकते हैं जैसे कि वे सामान्य तरीके थे। उस मामले में NullReferenceException पूरी तरह से गलत होगा।

6

के बाद से विस्तार के तरीकों में इस्तेमाल किया जा सकता सी # 2.0, और वे (आप उन्हें विस्तार तरीके के रूप में उपयोग करने के लिए नहीं है) सिर्फ स्थिर तरीकों की तरह कहा जा सकता है, तो आप ArgumentNullException उपयोग करना चाहिए।

सिर्फ इसलिए कि देखें इस प्रकार के तरीकों की तरह इसका मतलब यह नहीं है कि वे हैं, या हमेशा एक जैसा कहा जाता है।

19
सभी अन्य उत्तर (जो अच्छा कर रहे हैं) मुझे लगता है कि यह क्या माइक्रोसॉफ्ट स्थिरता की खातिर करता है पर देख रहे हैं लायक है ... और Enumerable में विस्तार तरीके के रूप में अब तक सब फेंक ArgumentNullException मैं देख सकता हूँ के अलावा

+0

महान विचार, मैंने खुद यह किया था, ऐसा नहीं किया, यकीन नहीं क्यों! ;-) –

+1

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

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