इस प्रश्न के लिए कोई आसान जवाब नहीं है। कोई भी जो हमेशा एक या दूसरे का उपयोग करता है, मेरी राय में आपको खराब सलाह दे रहा है।
वास्तव में कई अलग-अलग विधियां हैं जिन्हें आप ऑब्जेक्ट इंस्टेंस की तुलना करने के लिए कॉल कर सकते हैं। दो वस्तु उदाहरणों a
और b
देखते हुए, आप लिख सकते हैं:
Object.Equals(a,b)
Object.ReferenceEquals(a,b)
a.Equals(b)
a == b
ये सब अलग अलग बातें कर सकता है!
Object.Equals(a,b)
जाएगा (डिफ़ॉल्ट रूप से) संदर्भ प्रकार और मूल्य प्रकार पर बिटवाइज़ तुलना पर संदर्भ समानता तुलना करते हैं।MSDN प्रलेखीकरण से:
बराबर के डिफ़ॉल्ट कार्यान्वयन संदर्भ प्रकार के लिए संदर्भ समानता, और मूल्य प्रकार के लिए बिटवाइज़ समानता का समर्थन करता है। संदर्भ समानता का अर्थ ऑब्जेक्ट संदर्भ है जो की तुलना में उसी ऑब्जेक्ट को संदर्भित करता है। बिटवाईव समानता का अर्थ है की तुलना में तुलना की जाती है, उसी बाइनरी प्रतिनिधित्व है।
ध्यान दें कि व्युत्पन्न प्रकार बराबर विधि को लागू मूल्य समानता पर ओवरराइड कर सकता है। मान समानता का अर्थ है तुलना की गई वस्तुओं समान मूल्य है लेकिन अलग बाइनरी प्रस्तुतिकरण हैं।
ऊपर दिए गए अंतिम अनुच्छेद पर ध्यान दें ... हम बाद में इस पर चर्चा करेंगे।
Object.ReferenceEquals(a,b)
केवल संदर्भ समानता तुलना करता है। यदि पास किए गए प्रकार बॉक्स किए गए मान प्रकार हैं, तो परिणाम हमेशा false
होता है।
a.Equals(b)
Object
की आभासी उदाहरण विधि है, जो a
के प्रकार कुछ भी यह चाहता है ऐसा करने के लिए रद्द कर सकते थे कहता है। कॉल वर्चुअल प्रेषण का उपयोग करके किया जाता है, इसलिए चलने वाला कोड रनटाइम प्रकार a
पर निर्भर करता है।
a == b
a
की ** संकलन समय प्रकार * के स्थिर अतिभारित ऑपरेटर invokes। यदि उस ऑपरेटर का कार्यान्वयन a
या b
पर उदाहरण विधियों को आमंत्रित करता है, तो यह पैरामीटर के रनटाइम प्रकारों पर भी निर्भर हो सकता है। के बाद से प्रेषण अभिव्यक्ति में प्रकार के आधार पर किया जाता है, निम्नलिखित विभिन्न परिणाम हो सकता है:
Frog aFrog = new Frog();
Frog bFrog = new Frog();
Animal aAnimal = aFrog;
Animal bAnimal = bFrog;
// not necessarily equal...
bool areEqualFrogs = aFrog == bFrog;
bool areEqualAnimals = aAnimal = bAnimal;
तो, हाँ, वहाँ operator ==
का उपयोग कर nulls के लिए जांच करने के लिए जोखिम है। प्रैक्टिस में, अधिकांश प्रकार ओवरलोड ==
- लेकिन कभी गारंटी नहीं है।
उदाहरण विधि Equals()
यहां बेहतर नहीं है। जबकि डिफ़ॉल्ट कार्यान्वयन संदर्भ/bitwise समानता जांच करता है, Equals()
सदस्य विधि को ओवरराइड करने के लिए एक प्रकार के लिए संभव है, इस मामले में इस कार्यान्वयन को बुलाया जाएगा। कार्यान्वयन की गई एक उपयोगकर्ता शून्य की तुलना करते समय भी जो चाहें उसे वापस कर सकता है।
लेकिन Object.Equals()
के स्थिर संस्करण के बारे में आप क्या पूछते हैं? क्या यह चल रहा उपयोगकर्ता कोड समाप्त हो सकता है? खैर, यह पता चला है कि जवाब हाँ है।
((object)a == (object)b) || (a != null && b != null && a.Equals(b))
आप खुद के लिए यह कोशिश कर सकते हैं: Object.Equals(a,b)
के कार्यान्वयन की तर्ज पर कुछ के लिए विस्तारित उपयोगकर्ता कोड जब न चलाने के लिए Object.Equals(a,b)
:
class Foo {
public override bool Equals(object obj) { return true; } }
var a = new Foo();
var b = new Foo();
Console.WriteLine(Object.Equals(a,b)); // outputs "True!"
एक परिणाम के रूप में, यह बयान के लिए संभव है कॉल के प्रकार null
हैं।ध्यान दें कि Object.Equals(a,b)
Equals()
के इंस्टेंस संस्करण को कॉल करता है जब तर्क में से कोई भी शून्य नहीं होता है।
संक्षेप में, आप किस प्रकार की तुलनात्मक व्यवहार प्राप्त करते हैं, इस पर निर्भर करता है कि आप किस विधि को कॉल करना चुनते हैं। हालांकि, यहां एक टिप्पणी: माइक्रोसॉफ्ट आधिकारिक तौर पर Object.Equals(a,b)
के आंतरिक व्यवहार को दस्तावेज नहीं करता है। आप एक लोहे के किसी अन्य कोड चल रहा है बिना अशक्त के लिए एक संदर्भ की तुलना में पहने गारंटी के की जरूरत है, तो आप Object.ReferenceEquals()
हैं:
Object.ReferenceEquals(item, null);
इस विधि आशय extremently स्पष्ट करता है - आप विशेष रूप से तुलना होने का परिणाम उम्मीद कर रहे हैं संदर्भ समानता के लिए दो संदर्भों में से। a.Equals(null)
या a == null
जो संभवतः:
"अरे, यह अजीब है, चलो इसके साथ की जगह है: यहाँ Object.Equals(a,null)
की तरह कुछ का उपयोग करने पर लाभ यह है कि यह कम संभावना है कि किसी को बाद में आकर कहेंगे है । अलग हो सकता है।
चलो कुछ व्यावहारिकता यहाँ इंजेक्षन हालांकि, करते हैं। अब तक हम तुलना के विभिन्न साधनों अलग परिणाम उपज के लिए क्षमता के बारे में बात की है हालांकि यह निश्चित रूप से मामला है, वहाँ कुछ प्रकार के होते हैं, जहां यह है wr के लिए सुरक्षित यह a == null
। अंतर्निहित .NET वर्ग जैसे String
और Nullable<T>
तुलना के लिए अच्छी तरह से परिभाषित अर्थशास्त्र है। इसके अलावा, वे sealed
हैं - विरासत के माध्यम से उनके व्यवहार में किसी भी बदलाव को रोकना। निम्नलिखित बहुत आम (और सही) है:
string s = ...
if(s == null) { ... }
यह अनावश्यक (और बदसूरत) है लिखने के लिए:
if(ReferenceEquals(s,null)) { ... }
तो कुछ सीमित मामलों में , का उपयोग कर ==
सुरक्षित, और उचित है।
मैंने सोचा कि मेरा जवाब (प्रॉक्सी द्वारा माइक्रोसॉफ्ट का जवाब) एक बहुत ही सरल जवाब है। – mquander
जैसे प्रश्न: * "क्या मुझे हमेशा एक्स/कभी नहीं करना चाहिए" * प्रश्न में विषय की बारीकियों के बारे में ज्ञान अंतर को इंगित करता है। मुझे लगा कि थोड़ा और विस्तार यहां स्पष्टीकरण के लिए उपयोगी होगा कि मुझे क्यों नहीं लगता कि एक साधारण उत्तर सार्थक है। – LBushkin
स्थैतिक 'ऑब्जेक्ट। एक्वाल्स (ए, बी)' विधि, वास्तव में, ऑब्जेक्ट 'ए' पर अधिभारित/वर्चुअल 'बराबर' विधि को कॉल कर सकती है। अगर मैं सही ढंग से याद करता हूं, तो यह कुछ ('ऑब्जेक्ट) ए == (ऑब्जेक्ट) बी) करता है। || (ए! = नल && बी! = नल और ए। एक्वाल्स (बी)) '। (यह 'शून्य' की तुलना करते समय अप्रासंगिक है, जो ओपी पूछता है, लेकिन सामान्य मामले के लिए प्रासंगिक है।) – LukeH