2012-09-17 9 views
26

मैं एक सह कार्यकर्ता है जो अपने अशक्त चेकों लेखन इस प्रकार के एक प्रशंसक है है:"myObject == null" की तुलना में संदर्भ संदर्भ (myObject, null) "बेहतर अभ्यास है?

if (!ReferenceEquals(myObject, null)) 

मैं, दूसरे हाथ पर, पढ़ने के लिए इस वाक्य रचना बोझिल पाते हैं और पसंद करते हैं:

if (myObject != null) 

मैं ऑपरेटर ओवरलोडिंग के संबंध में संदर्भ एक्वाल्स के गुणों पर चर्चा करने वाले कुछ लेख और स्टैक ओवरफ़्लो प्रश्न पाए गए हैं, लेकिन ऑपरेटर ओवरलोडिंग परिदृश्य के बाहर, संदर्भ एक्वाल्स बनाम == के लिए कोई लाभ है?

+2

ध्यान देने योग्य बात अपने दोस्त के संस्करण कम पढ़ी जा सकती है कि (जो एक मुद्दा जब चेक, परस्पर विनिमय कर रहे हो जाता है वर्थ के बराबर है जो वे आमतौर पर हैं)। – keyser

+0

इसके अलावा - यह उपरोक्त से भी बदतर है - आपको 'if (! Object.ReferenceEquals (myObject, null)) टाइप करना होगा - इसलिए यह वास्तविकता में वर्णित से भी लंबा है। –

+1

@ReedCopsey नहीं, आपको इसे टाइप करने की ज़रूरत नहीं है, क्योंकि आपकी विधि किसी वर्ग या संरचना के अंदर है जो स्थिर (संदर्भित 'विधि को अपनी (प्रत्यक्ष या अप्रत्यक्ष) बेस क्लास' System.Object' से प्राप्त करती है। तो उपर्युक्त के रूप में लिखना ठीक है (विरासत विधि को 'नई' पद्धति के साथ छिपाएं, लेकिन यह एक बुरा अपवाद है)। –

उत्तर

27

लेकिन ऑपरेटर ओवरलोडिंग परिदृश्य के बाहर, संदर्भ एक्वाल्स बनाम == के लिए कोई लाभ है?

नहीं - केवल लाभ (और मैं बहस चाहते हैं यह एक फायदा बारे में ज्यादा नहीं है) स्पष्ट रूप से Object.ReferenceEquals उपयोग करने के लिए हो सकता है कि इसका इस्तेमाल कभी नहीं होगा अतिभारित ऑपरेटर के बराबर होती है। गैर-अधिभारित मामले में, == Operator को स्ट्रिंग के अलावा सभी "संदर्भ प्रकारों" के लिए "दो वास्तविक ऑपरेशन एक ही ऑब्जेक्ट का संदर्भ देते हैं" के लिए परिभाषित किया गया है। इस प्रकार, इसके बराबर (बशर्ते इसे ओवरलोड नहीं किया गया हो)।

मैं, व्यक्तिगत रूप से, दूसरे वाक्यविन्यास का उपयोग करने का भी पक्ष लेता हूं, और इसे शून्य जांच के लिए अधिक रखरखाव ढूंढता हूं। मैं यह भी तर्क दूंगा कि किसी भी अधिभारित operator== को null के खिलाफ उचित जांच भी प्रदान करनी चाहिए, और जिस मामले में यह किसी कारण से नहीं था (जो अजीब होगा), उस निर्णय के पीछे एक विशिष्ट तर्क होगा जो आपको कारण देगा अधिभार का उपयोग करना चाहते हैं, ReferenceEquals नहीं।

3

ठीक है, अगर कोई == या! = ऑपरेटरों को ओवरराइड करना था तो वे उन्हें जो कुछ भी चाहते थे उन्हें कर सकते थे। यह return true; या return false; जैसे वास्तविक अर्थ भी हो सकता है। इसके अतिरिक्त, यदि ओवरलोडेड ऑपरेटर है तो यह एक सभ्य मौका है कि यह प्रदर्शन नहीं करेगा साथ ही ReferenceEquals (गारंटी नहीं है, और संभवतः यह मामला महत्वपूर्ण नहीं है, लेकिन फिर भी)।

यह कहकर कि, किसी भी अधिभारित ऑपरेटर के किसी भी समझदार कार्यान्वयन के साथ यह एक समस्या होने की संभावना नहीं है। मैं व्यक्तिगत रूप से ReferenceEquals का उपयोग नहीं करता जब तक कि मेरे पास उस प्रकार या उस विशेष उदाहरण में == ऑपरेटर का उपयोग न करने का एक अनिवार्य कारण है।

+5

यदि ओवरलोडेड '==' ऑपरेटर खराब/अनुचित रूप से लागू किया गया है, तो * वह * बग जिसे ठीक किया जाना चाहिए। 'ReferenceEquals()' का उपयोग कर इसके आसपास काम करना सही तरीका नहीं है। –

+3

@MichaelBurr आप मानते हैं कि आपके पास इस प्रकार का नियंत्रण है और इसलिए इसे ठीक करने की क्षमता है। यह हमेशा मामला नहीं है। – Servy

1

शून्य जांच के संदर्भ में, दोनों को हमेशा एक ही परिणाम वापस करना चाहिए। यदि कोई गैर-शून्य संदर्भ कभी भी शून्य (बराबर ऑब्जेक्ट पैटर्न का उपयोग करते समय) के बराबर होता है, भले ही संदर्भ Equals या == ऑपरेटर का उपयोग किया गया हो, यह बहुत खराब चीज़ है। तो, उस परिदृश्य में मैं == /! = का उपयोग करूंगा।

मैं कहूँगा कि, अगर == ऑपरेटर अतिभारित रहे थे, ReferenceEquals का उपयोग कर हो सकता है थोड़ा तेजी से। पहली चीज एक ओवरलोडेड == करना चाहिए यह देखना है कि दो चर एक ही ऑब्जेक्ट को इंगित करते हैं, इसलिए ओवरलोडेड ऑपरेटर के मामले में आप कॉल स्टैक पर एक अतिरिक्त फ्रेम के साथ समाप्त होते हैं। ReferenceEquals का उपयोग करने से यह भी गारंटी मिलती है कि केवल जांच की गई है।

मैं आम तौर पर किसी भी अन्य परिदृश्य में == /! = का उपयोग करता हूं। पूरा विचार यह है कि ऑपरेटर "समानता" को परिभाषित करता है; यह हमेशा संदर्भित नहीं होता है (वास्तव में, अधिकांश यौगिक वस्तुओं की समानता के लिए संरचनात्मक रूप से तुलना की जानी चाहिए; वे बराबर हैं यदि उनके सदस्य बराबर हैं)।ऑब्जेक्ट, सैद्धांतिक रूप से, जानता है कि समानता, सापेक्ष आदेश इत्यादि के लिए खुद को किसी अन्य वस्तु से तुलना करना सर्वोत्तम है और तर्क के एक बहुत ही विशिष्ट और संभवतः गलत टुकड़े को हार्डकोड करने के बजाय, आपको भाषा की ऑब्जेक्ट उन्मुख प्रकृति का उपयोग करना चाहिए ऑब्जेक्ट को आपको बताएं कि यह किसी और चीज़ के बराबर है या नहीं।

0

वीबी.नेट टैग शायद इस प्रश्न में शामिल नहीं किया जाना चाहिए क्योंकि इसे अन्यथा उल्लेख नहीं किया गया है, लेकिन, पूर्णता के लिए, IsObject.ReferenceEquals के बराबर है और इसलिए हमेशा उस कॉल के बजाय उपयोग किया जा सकता है।

0

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

मैं व्यक्तिगत रूप से संदर्भ एक्वाल्स का उपयोग करता हूं, लेकिन केवल उन स्थानों पर जहां मैं वास्तव में अंतिम घड़ी चक्रों को निचोड़ने के लिए tweaking कर रहा हूं (स्थानों को संभवतः प्रति सेकंड लाखों बार कहा जाता है)। या जब मेरे पास जेनेरिक के मामले में, इस प्रकार पर कोई नियंत्रण नहीं है। ... लेकिन फिर जब प्रदर्शन वास्तव में महत्वपूर्ण है।

+2

ध्यान रखें कि ऑपरेटर आभासी नहीं हैं। यह * संकलन समय प्रकार * है जो रनटाइम प्रकार नहीं है। जेनेरिकों के मामले में, जब तक कि एक प्रकार की बाधा नहीं होती है जो '==' ऑपरेटर को ओवरलोड करता है, तो '==' का उपयोग हमेशा 'ऑब्जेक्ट' ओवरलोड का उपयोग किया जा रहा है, जिसके लिए कोई चेक नहीं करना चाहिए और बस 'संदर्भ एक्वाल्स' कॉल करता है। उन मामलों में यह न केवल कार्यात्मक रूप से समकक्ष होगा, बल्कि प्रदर्शन लगभग समान भी होगा। यह जेनेरिक को * संदर्भ * की बजाय '==' का उपयोग करने के लिए * सुरक्षित * समय में से एक बनाता है। – Servy

6
# 7 सी के साथ

, तो आप उपयोग कर सकते हैं:

if (!(myObject is null)) 

यह

if (!ReferenceEquals(myObject, null)) 
संबंधित मुद्दे