2012-04-16 13 views
6

संभव डुप्लिकेट:
Why check this != null?String.Equals (ऑब्जेक्ट obj) क्यों जांचता है यह देखने के लिए कि यह == शून्य है?

// Determines whether two strings match. 
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
public override bool Equals(Object obj) 
{ 
    //this is necessary to guard against reverse-pinvokes and 
    //other callers who do not use the callvirt instruction 
    if (this == null) 
     throw new NullReferenceException(); 

    String str = obj as String; 
    if (str == null) 
     return false; 

    if (Object.ReferenceEquals(this, obj)) 
     return true; 

    return EqualsHelper(this, str); 
} 

हिस्सा मुझे समझ नहीं आता तथ्य यह है कि यह वर्तमान उदाहरण, this के लिए जाँच कर रहा है, अशक्त के खिलाफ है। टिप्पणी थोड़ा उलझन में है, इसलिए मैं सोच रहा था कि उस टिप्पणी का वास्तव में क्या अर्थ है?

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

+0

@FlorianGreinacher: संभव डुप्लिकेट नहीं, लेकिन काफी सटीक डुप्लिकेट, लॉल। मुझे आश्चर्य है कि जब मैं अपना प्रश्न लिख रहा था तो यह "संबंधित" में क्यों नहीं आया? –

उत्तर

6

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

ध्यान दें कि भले ही आप शून्य this के साथ कॉल करने का प्रबंधन करते हैं और आपके पास गार्ड नहीं है, तो ऐसा होगा कि अपवाद थोड़ा अलग होगा। यह एक अलग अपवाद हो सकता है और इसे किसी दूसरे सदस्य द्वारा फेंक दिया जा सकता है, लेकिन अन्यथा यह कोई फर्क नहीं पड़ता है।

दूसरे शब्दों में, यदि शून्य जांच नहीं थी, तो EqualsHelper (या इसकी कॉलियों में से एक) Equals के बजाय अपवाद फेंक देगा। चूंकि उपयोगकर्ता-दृश्य फ़ंक्शन के आंतरिक छिपाने के लिए वांछनीय है, इसलिए शुरुआत में चेक को सही रखना समझ में आता है।

2
  • सी # और वीबी.नेट जैसी भाषाएं उदाहरण उदाहरण विधि से पहले NullReference को फेंकने के लिए कॉलवर्ट का उपयोग करती हैं (यह == शून्य) चेक आवश्यक नहीं हैं।
  • एफ # और प्रबंधित सी ++ (अधिकांश समय) जैसी भाषाएं कॉल निर्देश का उपयोग करती हैं जहां आप इस पॉइंटर को शून्य के साथ एक इंस्टेंस विधि में प्राप्त कर सकते हैं। (यह == शून्य) का असर पड़ता है।

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

यदि आप .NET कक्षाओं के अंदर चेक देखते हैं तो यह स्पष्ट है कि केवल कुछ प्रमुख वर्गों जैसे स्ट्रिंग में ऐसे गार्ड होते हैं। इंडेक्सऑफ जैसी अन्य विधियां इसके खिलाफ सुरक्षा नहीं करती हैं। यह असंगत है लेकिन मुझे लगता है कि इस तरह के डबल नल चेक के लिए प्रदर्शन दंड प्रयास के लायक नहीं थे क्योंकि बीसीएल के अधिकांश उपयोगकर्ता ऐसी भाषाएं हैं जो कॉलवर्ट निर्देश का उपयोग करते हैं जहां दूसरी नल चेक मदद नहीं करता है।

+1

एफ # में, 'चलो एक्स = "ए"।बराबर ("बी") अभी भी 'कॉलवर्ट' के लिए संकलित है – colinfang

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