2010-12-28 17 views
6

MSDN Guidelines for Overloading Equals() and Operator == राज्य में == ऑपरेटर ओवरराइड:गैर अपरिवर्तनीय प्रकार

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

क्या कोई बोल्ड के पीछे तर्क की व्याख्या कर सकता है?

संपादित - इसके अलावा, इस निर्देश केवल == ऑपरेटर के लिए प्रासंगिक है, या यह रूप में अच्छी तरह Equals विधि के लिए क्या मतलब है?

उत्तर

16

मेरा शिक्षित अनुमान चीजों को .NET में निर्मित प्रकारों की तरह काम करने के लिए करना होगा, अर्थात् == को यथासंभव संदर्भ समानता की तरह काम करना चाहिए, और समानताएं जहां संभव हो वैल्यू समानता की तरह काम करनी चाहिए। == और Equals के बीच वास्तविक अंतर पर विचार करें:

object myObj = new Integer(4); 
object myObj2 = new Integer(4); 

//Note that == is only called if the ref'd objects are cast as a type 
//overloading it. 
myObj == myObj2; //False (???) 
myObj.Equals(myObj2); //True (This call is virtual) 

//Set the references equal to each other -- note that the operator== 
//comparison now works. 
myObj2 = myObj; 
myObj == myObj2; //True 
myObj.Equals(myObj2); //True 

यह व्यवहार विशेष रूप से नए प्रोग्रामर करने के लिए, असंगत और भ्रामक निश्चित रूप से है - लेकिन यह संदर्भ तुलना और मूल्य तुलना के बीच अंतर को दर्शाता है।

यदि आप इस एमएसडीएन दिशानिर्देश का पालन करते हैं, तो आप स्ट्रिंग जैसे महत्वपूर्ण वर्गों द्वारा दिशानिर्देशों का पालन कर रहे हैं। असल में - यदि == का उपयोग करके तुलना सफल होती है, तो प्रोग्रामर जानता है कि वह तुलना हमेशा सफल रहेगी, जब तक कि संदर्भ शामिल न हों, नई वस्तुओं को सौंपा नहीं जाता है। प्रोग्रामर वस्तुओं अलग किया जा रहा है की सामग्री के बारे में चिंता कभी नहीं की जरूरत है, क्योंकि वे कभी नहीं अलग हो जाएगा:

//Mutable type 
var mutable1 = new Mutable(1); 
var mutable2 = mutable1; 
mutable1 == mutable2; //true 
mutable1.MutateToSomethingElse(56); 
mutable1 == mutable2; //still true, even after modification 
//This is consistent with the framework. (Because the references are the same, 
//reference and value equality are the same.) Consider if == were overloaded, 
//and there was a difference between reference and value equality: 

var mutable1 = new Mutable(1); 
var mutable2 = new Mutable(1); 
mutable1 == mutable2; //true 
mutable1.MutateToSomethingElse(56); 
mutable1 == mutable2; //oops -- not true anymore 
//This is inconsistent with, say, "string", because it cannot mutate. 

यह नीचे फोड़े के लिए वहाँ दिशानिर्देश के लिए कोई वास्तविक तकनीकी कारण नहीं है कि - यह के अनुरूप रहने के लिए सिर्फ है ढांचे में बाकी वर्गों।

+1

+1 यह स्पष्ट रूप से उत्तर –

+0

बहुत अच्छा विचार है। – jason

0

मान लें कि आपके पास एक परिवर्तनीय प्रकार ए है और आप टाइप ए के सेट या ऑब्जेक्ट्स बनाते हैं। सेट में ऑब्जेक्ट जोड़ना विफल होना चाहिए यदि यह ऑब्जेक्ट सेट में पहले से मौजूद है।

अब मान लें कि आप सेट पर कोई ऑब्जेक्ट जोड़ते हैं, और फिर आप इसकी गुणों को बदलते हैं ताकि यह सेट में किसी अन्य ऑब्जेक्ट के बराबर हो। आपने एक अवैध राज्य बनाया है, जहां सेट में दो ऑब्जेक्ट्स बराबर हैं।

+0

लेकिन '==' के बजाय' बराबर' का उपयोग करके इस समस्या को ठीक नहीं किया गया है। –

+0

एक और दिशानिर्देश हमेशा '==' और 'समान()' को ओवरराइड करना है। और 'getHashCoe()' भी मिलता है। –

+0

दरअसल यह करता है - समान रूप से समान है। अंतर देखने के लिए दोनों के लिए प्रलेखन पढ़ें। – TomTom

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