C # के बीच अंतर == और बराबर ()


548

मैं एक Silverlight अनुप्रयोग है कि 2 तार तुलना किसी कारण से जब मैं का उपयोग में एक शर्त है ==यह रिटर्न झूठी जबकि .Equals()रिटर्न सच

यहाँ कोड है:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

ऐसा होने का कोई कारण?


2
इन्हें भी देखें: stackoverflow.com/questions/144530/or-equals
तीर

8
स्ट्रिंग ओवरराइड करता है ==, लेकिन ऑपरेटर बहुरूपी नहीं होते हैं। इस कोड में, ==ऑपरेटर को टाइप पर आमंत्रित किया जाता है object, जो एक मान के बजाय एक पहचान तुलना करता है।
आकर्षित नोक

12
@DrewNoakes की टिप्पणी पर विस्तार करने के लिए: संकलक संचालकों ==के संकलन-समय प्रकार के आधार पर एक अधिभार चुनता है। Contentसंपत्ति है object। ऑपरेटर्स वर्चुअल नहीं होते हैं, इसलिए डिफॉल्ट इम्प्लीमेंटेशन ऑफ़ ==कॉल कहा जाता है, जिससे रेफरेंस इक्वैलिटी की तुलना की जाती है। बराबरी के साथ, कॉल वर्चुअल विधि पर जाता है object.Equals(object); stringइस पद्धति को ओवरराइड करता है और स्ट्रिंग सामग्री पर क्रमिक तुलना करता है। Msdn.microsoft.com/en-us/library/fkfd9eh8(v=vs.110).aspx और referenceource.microsoft.com/#mscorlib/system/string.cs,507 देखें ।
फोगोग ph

6
@ फोग की व्याख्या सटीक है। यह ध्यान दिया जाना चाहिए कि जब बाएं-हाथ की तरफ ==संकलित-समय प्रकार होता है objectऔर दाहिने-हाथ की तरफ संकलन-समय प्रकार होता है string, तो C # संकलक को (समस्याग्रस्त, इस मामले में) अधिभार उठाना चाहिए operator ==(object, object); लेकिन यह एक संकलन-समय चेतावनी जारी करेगा कि यह अनायास ही हो सकता है। तो संकलन-समय की चेतावनी पढ़ें ! समस्या को ठीक करने के लिए और अभी भी उपयोग करने के लिए ==, बाएं हाथ की ओर कास्ट करें string। अगर मुझे सही से याद है, तो चेतावनी पाठ केवल यही बताता है।
जेपी स्टिग नीलसन 15

1
संकलक की चेतावनी पढ़ने की सलाह के लिए @JeppeStigNielsen +1। इससे भी बेहतर: सभी को उन पर ध्यान देने के लिए मजबूर करने के लिए चेतावनियों-त्रुटियों के विकल्प को चालू करें।
फोगोग

जवाबों:


429

जब ==इसे अभिव्यक्ति के प्रकार पर प्रयोग किया जाता है object, तो यह हल हो जाएगा System.Object.ReferenceEquals

Equalsसिर्फ एक है virtualतो ओवरराइड संस्करण का उपयोग किया जाएगा (जो, के लिए, इस तरह के रूप विधि और बर्ताव करता है stringप्रकार सामग्री तुलना)।


56
जब तक ऑपरेटर विशेष रूप से कक्षा में कार्यान्वित किया जाता है
डोमिनिक क्रोनिन

23
@DominicCronin यह सच नहीं है। यहां तक ​​कि अगर == को कक्षा में लागू किया जाता है, तो इसे अनदेखा कर दिया जाएगा क्योंकि तुलना के बाईं ओर का प्रकार ऑब्जेक्ट है। ऐसा लगता है कि संचालक अधिभार संकलित समय पर निर्धारित किए जाते हैं और संकलन के समय यह सब जानते हैं कि बाएं हाथ एक वस्तु है।
22 सितंबर को माइक कुल्स

4
@DominicCronin मेरा मानना ​​है कि आपका पहला कथन उसमे सही है == ऑब्जेक्ट को हल करेगा लेकिन आपका दूसरा स्टेटमेंट जो ऑपरेटर ओवरलोड एक समान तरीके से हल करता है वह नहीं है। वे काफी भिन्न हैं, यही वजह है कि। स्ट्रिंग स्ट्रिंग का समाधान करेगी जबकि == ऑब्जेक्ट पर हल करेगी।
मीकुल्ल्स ने

8
स्पष्ट रूप से, objectप्रकार (नोटिस monospace फ़ॉन्ट) तकनीकी रूप से "प्रकार की अभिव्यक्ति करने के लिए है System.Object"। यह रनटाइम प्रकार के उदाहरण के साथ संदर्भित करने के लिए कुछ भी नहीं करता है। मुझे लगता है कि बयान "उपयोगकर्ता-परिभाषित ऑपरेटरों को virtualतरीकों की तरह व्यवहार किया जाता है " बेहद भ्रामक है। उन्हें अतिभारित तरीकों की तरह व्यवहार किया जाता है और केवल संचालकों के संकलन-समय प्रकार पर निर्भर करता है। वास्तव में, उम्मीदवार निर्धारित उपयोगकर्ता ऑपरेटरों के सेट के बाद गणना की जाती है, बाकी बाध्यकारी प्रक्रिया बिल्कुल विधि अधिभार संकल्प एल्गोरिथ्म होगी
मेहरदाद अफश्री

4
@DominicCronin भ्रामक हिस्सा यह है कि virtualविधि रिज़ॉल्यूशन वास्तविक रनटाइम प्रकार के उदाहरण पर निर्भर करता है, जबकि ऑपरेटर ओवरलोड रिज़ॉल्यूशन में इसे पूरी तरह से अनदेखा किया जाता है, और यह वास्तव में मेरे उत्तर का पूरा बिंदु है।
मेहरदाद अफश्री

314

किसी ऑब्जेक्ट संदर्भ की स्ट्रिंग से तुलना करते हुए (भले ही ऑब्जेक्ट स्ट्रिंग को संदर्भित करता है), ==स्ट्रिंग वर्ग के लिए विशेष ऑपरेटर के विशेष व्यवहार को अनदेखा किया जाता है।

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

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

आउटपुट है:

True True True
False True True
False False True

8
सटीक। '==' ऑपरेटर ऑब्जेक्ट संदर्भों (उथले तुलना) की तुलना करता है जबकि .Equals () ऑब्जेक्ट सामग्री (गहरी तुलना) की तुलना करता है। जैसा कि @mehrdad ने कहा, .Equals () उस गहरी सामग्री की तुलना प्रदान करने के लिए ओवरराइड है।
एंड्रयू

1
मैं यहां पद छोड़ दूंगा क्योंकि मुझे लगता है कि इस पर जोर देना मूल्यवान है कि क्या नहीं हो रहा है क्योंकि आपको इसे महसूस करने के लिए करीब से ध्यान देना होगा। (और मुझे लगता है कि सही और गलत समझ को प्रदर्शित करने के लिए कोड भी सार्थक है।) मुझे उम्मीद है कि रेटिंग 0. से नीचे नहीं जाएगी
BlueMonkMN

5
निश्चित रूप से स्ट्रिंग एक कस्टम == ऑपरेटर को लागू करता है। यदि यह नहीं होता तो == सामग्री की तुलना नहीं करता। इसलिए स्ट्रिंग यहां उपयोग करने के लिए एक बुरा उदाहरण है, क्योंकि यह हमें सामान्य मामले को समझने में मदद नहीं करता है जहां कोई कस्टम ऑपरेटर परिभाषित नहीं किया गया है।
डोमिनिक क्रोनिन

6
महाकाव्य कोड उदाहरण के लिए +1, जिसने मुझे इसका अर्थ समझा। स्टैटिक प्रकार (लेफ्ट हैंड साइड टाइप) के सामान्य मामले को वस्तु के रूप में दिखाता है और स्टैटिक प्रकार के विशिष्ट मामले (/ RHS प्रकार) को स्ट्रिंग किया जा रहा है। और स्ट्रिंग इंटर्निंग पर अच्छी तरह से छूता है।
बार्लॉप

2
@badsamaritan स्ट्रिंग इंटर्निंग के कारण
अलेक्जेंडर डर्क

46

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

जब मैं एक नए प्रकार के साथ काम कर रहा हूं, जिसकी परिभाषा प्रवाह में है या जेनेरिक एल्गोरिदम लिखना है, तो मुझे लगता है कि सबसे अच्छा अभ्यास निम्नलिखित है

  • यदि मैं C # में संदर्भों की तुलना करना चाहता हूं, तो मैं Object.ReferenceEqualsसीधे उपयोग करता हूं (सामान्य मामले में आवश्यक नहीं)
  • यदि मैं उन मूल्यों की तुलना करना चाहता हूं जो मैं उपयोग करता हूं EqualityComparer<T>.Default

कुछ मामलों में जब मुझे लगता है कि ==अस्पष्ट है तो मैं स्पष्ट रूप Object.Referenceसे अस्पष्टता को दूर करने के लिए कोड में बराबर का उपयोग करूंगा ।

एरिक लिपर्ट ने हाल ही में इस विषय पर एक ब्लॉग पोस्ट किया था कि सीएलआर में समानता के 2 तरीके क्यों हैं। यह पढ़ने लायक है


खैर जारेड, आप सीधे जेफ के प्रसिद्ध का उल्लंघन करते हैं "सबसे अच्छा कोड यहां कोई कोड नहीं है।" क्या यह वास्तव में उचित है? दूसरी ओर, मैं देख सकता हूँ कि यह कहाँ से उपजा है और यह शब्दार्थ को स्पष्ट करने के लिए वांछनीय क्यों हो सकता है। इस मामले के लिए, मैं ऑब्जेक्ट समानता से निपटने के वीबी के तरीके को बहुत पसंद करता हूं। यह छोटा और असंदिग्ध है।
कोनराड रुडोल्फ

@ कोनराड, मुझे वास्तव में कहना चाहिए "जब मैं एक प्रकार से अपरिचित हूं, तो मुझे लगता है कि सबसे अच्छा अभ्यास निम्नलिखित है"। हाँ VB के यहाँ बेहतर शब्दार्थ है क्योंकि यह वास्तव में मूल्य और संदर्भ समानता को अलग करता है। सी # दोनों को एक साथ मिलाता है और यह कभी-कभी अस्पष्टता त्रुटियों का कारण बनता है।
जारेदपार

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

20

== संचालक

  1. यदि ऑपरेंड वैल्यू टाइप हैं और उनके मान बराबर हैं, तो यह सही और गलत है।
  2. यदि ऑपरेंड स्ट्रिंग के अपवाद के साथ संदर्भ प्रकार हैं और दोनों एक ही उदाहरण (समान ऑब्जेक्ट) को संदर्भित करते हैं , तो यह सही और गलत है।
  3. यदि ऑपरेंड स्ट्रिंग प्रकार के होते हैं और उनके मान समान होते हैं, तो यह सही और गलत है।

.Equals

  1. यदि ऑपरेंड संदर्भ प्रकार हैं , तो यह संदर्भ समानता करता है यदि दोनों एक ही उदाहरण (समान ऑब्जेक्ट) को संदर्भित करते हैं , तो यह सही और गलत है।
  2. यदि ऑपरेंड वैल्यू टाइप हैं, तो == ऑपरेटर के विपरीत यह उनके प्रकार के लिए पहले जाँच करता है और यदि उनके प्रकार समान होते हैं तो यह == ऑपरेटर या अन्य गलत रिटर्न देता है।

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

19

सबसे पहले, वहाँ है एक फर्क। संख्या के लिए

> 2 == 2.0
True

> 2.Equals(2.0)
False

और तार के लिए

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

दोनों मामलों में, की ==तुलना में अधिक उपयोगी व्यवहार करता है.Equals


2
मुझे यकीन नहीं है कि मैं ==एक अच्छी बात होने के लिए ऑपरेटर के साथ फ़्लोटिंग-पॉइंट प्रकारों के अभिन्न प्रकार के संबंध का संबंध रखता हूं । उदाहरण के लिए, 16777216.0f के बराबर होना चाहिए (int) 16777217, (डबल) 16777217.0, दोनों, या दोनों नहीं? अभिन्न प्रकारों के बीच तुलना ठीक है, लेकिन फ्लोटिंग-पॉइंट तुलनाओं को केवल आईएमएचओ को उन मूल्यों के साथ किया जाना चाहिए जो स्पष्ट रूप से मिलान प्रकारों के लिए डाली जाती हैं। ए के floatअलावा किसी चीज़ की तुलना float, या ए के doubleअलावा किसी चीज़ की तुलना में double, मुझे एक प्रमुख कोड गंध के रूप में प्रभावित करता है जिसे निदान के बिना संकलन नहीं करना चाहिए।
सुपरकैट

1
@supercat मैं सहमत हूं - यह व्यथित है कि x == yइसका मतलब x/3 == y/3(कोशिश x = 5और y = 5.0) नहीं है।
कर्नल पैनिक

मैं /पूर्णांक विभाजन के उपयोग को C # और Java के डिज़ाइन में दोष मानता हूं । पास्कल divऔर यहां तक ​​कि VB.NET के ` are much better. The problems with == `भी बदतर हैं, हालांकि: x==yऔर y==zइसका मतलब यह नहीं है x==z(मेरी पिछली टिप्पणी में तीन संख्याओं पर विचार करें)। संबंध का सुझाव है, भले ही के रूप में xऔर yदोनों floatया दोनों double, x.equals((Object)y)मतलब यह नहीं है कि 1.0f/x == 1.0f / y` (अगर मैं अपने druthers था, यह गारंटी है कि, भले ही ==सकारात्मक भेद नहीं है और शून्य, Equalsचाहिए)।
सुपरकैट

यह सामान्य है, क्योंकि बराबर () का पहला पैरामीटर एक स्ट्रिंग है!
व्हिपलैश

17

जहाँ तक मैं समझता हूँ इसका उत्तर सरल है:

  1. == वस्तु संदर्भों की तुलना करता है।
  2. .Equals वस्तु सामग्री की तुलना करता है।
  3. String डेटाटाइप हमेशा सामग्री तुलना की तरह कार्य करता है।

मुझे आशा है कि मैं सही हूं और इसने आपके प्रश्न का उत्तर दिया।


15

मुझे लगता है कि यदि आप एक स्ट्रिंग के लिए अपनी वस्तु डाली तो यह सही ढंग से काम करेगा। यही कारण है कि संकलक आपको एक चेतावनी देगा:

संभावित अनपेक्षित संदर्भ तुलना; मान की तुलना प्राप्त करने के लिए, 'स्ट्रिंग' टाइप करने के लिए बाएं हाथ की तरफ कास्ट करें


1
बिल्कुल सही। @DominicCronin: हमेशा संकलन-समय की चेतावनी देखें। यदि आपके पास है object expr = XXX; if (expr == "Energy") { ... }, तो चूंकि बायाँ हाथ संकलन-समय प्रकार का है object, इसलिए संकलक को अधिभार का उपयोग करना होगा operator ==(object, object)। यह संदर्भ समानता के लिए जाँच करता है। चाहे वह दे trueया स्ट्रिंग इंटर्निंग केfalse कारण भविष्यवाणी करना कठिन हो सकता है । यदि आपको पता है कि बाएं हाथ की तरफ या तो टाइप की गई है , तो उपयोग करने से पहले बाएं हाथ की तरफ कास्ट करें । nullstringstring==
जेपी स्टिग नीलसन

उस दूसरे तरीके का हिस्सा रखना। == (यह निर्धारित करने में कि क्या यह संदर्भ समानता या मूल्य समानता का उपयोग करता है) संकलन समय प्रकार / स्थिर प्रकार / बाएं हाथ की तरफ प्रकार पर निर्भर करता है। (यह वह प्रकार है जो एक संकलन समय विश्लेषण में हल किया गया है)। रनटाइम प्रकार / गतिशील प्रकार / RHS प्रकार के बजाय। BlueMonkMN का कोड दिखाता है कि, हालांकि कास्टिंग के साथ नहीं।
बार्लॉप

5

क्योंकि .Equalविधि के स्थिर संस्करण का अब तक उल्लेख नहीं किया गया था, मैं इसे संक्षेप में जोड़ने और 3 विविधताओं की तुलना करने के लिए यहां जोड़ना चाहूंगा।

MyString.Equals("Somestring"))          //Method 1
MyString == "Somestring"                //Method 2
String.Equals("Somestring", MyString);  //Method 3 (static String.Equals method) - better

MyStringवह चर कहां है जो कोड में कहीं और से आता है।

पृष्ठभूमि की जानकारी और गर्मियों के लिए:

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

C # में विधि 1 या विधि 2 का उपयोग करते हुए तार की तुलना करने के लिए कोई व्यावहारिक अंतर नहीं है जब तक कि दोनों प्रकार स्ट्रिंग के नहीं हैं। हालाँकि, यदि कोई अशक्त है, तो एक दूसरे प्रकार का होता है (जैसे एक पूर्णांक), या कोई एक ऐसी वस्तु का प्रतिनिधित्व करता है, जिसका एक अलग संदर्भ होता है, तो, जैसा कि प्रारंभिक प्रश्न दिखाता है, आप अनुभव कर सकते हैं कि समानता के लिए सामग्री की तुलना करने से क्या हो सकता है तुम आशा करते हो।

सुझाया गया समाधान:

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

   bool areEqual = String.Equals("Somestring", MyString);  

यह लिखना थोड़ा अधिक है, लेकिन मेरी राय में, उपयोग करने के लिए सुरक्षित है।

Microsoft से कॉपी की गई कुछ जानकारी इस प्रकार है:

public static bool Equals (string a, string b);

पैरामीटर

a तार

तुलना करने वाला पहला तार, या null

b तार

तुलना करने के लिए दूसरा तार, या null

रिटर्न Boolean

trueयदि मूल्य का मान aसमान है b; अन्यथा, false। यदि दोनों हैं aऔर bहैं null, तो विधि वापस आ जाती है true


5

पहले से ही अच्छे उत्तरों के अतिरिक्त: यह व्यवहार स्ट्रिंग्स तक सीमित नहीं है या विभिन्न संख्याओं की तुलना नहीं करता है। भले ही दोनों तत्व एक ही अंतर्निहित प्रकार के प्रकार के हों। "==" काम नहीं करेगा।

निम्न स्क्रीनशॉट दो ऑब्जेक्ट {int} - मानों की तुलना करने के परिणाम दिखाता है

VS2017 से उदाहरण


2

मैं यहां थोड़ा भ्रमित हूं। यदि रनटाइम प्रकार की सामग्री टाइप स्ट्रिंग की है, तो == और बराबर दोनों को सही होना चाहिए। हालाँकि, जब से ऐसा प्रतीत नहीं होता है, तब रनटाइम प्रकार की सामग्री स्ट्रिंग नहीं होती है और उस पर कॉल करना बराबर होता है जो एक संदर्भात्मक समानता करता है और यह बताता है कि क्यों समान ("ऊर्जा हमला") विफल हो जाता है। हालांकि, दूसरे मामले में, जिस निर्णय को अधिभार == स्थिर ऑपरेटर कहा जाना चाहिए, वह संकलन समय पर किया जाता है और यह निर्णय == (स्ट्रिंग, स्ट्रिंग) प्रतीत होता है। यह मुझे सुझाव देता है कि सामग्री स्ट्रिंग को एक अंतर्निहित रूपांतरण प्रदान करती है।


2
आप इसे वापस सामने है। एक शुरुआत के लिए बराबर ("ऊर्जा हमला") विफल नहीं होता है, == वह है जो झूठी वापसी करता है। == विफल रहता है क्योंकि यह ऑब्जेक्ट से == का उपयोग कर रहा है, न कि स्ट्रिंग से।
माइककूल

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

2

@BlueMonkMN द्वारा पहले के उत्तर का एक और आयाम है। अतिरिक्त आयाम यह है कि @ दारसीर के शीर्षक प्रश्न का उत्तर जैसा कि कहा गया है, यह इस बात पर भी निर्भर करता है कि हम stringमूल्य पर कैसे पहुंचे । उदाहरण देकर स्पष्ट करने के लिए:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));

Console.WriteLine("\n  Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Console.WriteLine("\n  Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

आउटपुट है:

True True True

  Case1 - A method changes the value:
False True True
False False True

  Case2 - Having only literals allows to arrive at a literal:
True True True
True True True

2

उत्तर के लिए एक और बिंदु जोड़ना।

.EqualsTo() विधि आपको संस्कृति और संवेदनशील मामलों की तुलना करने का प्रावधान देती है।


0

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

ध्यान दें कि कुछ अन्य भाषाएं दो समानता वाले चेक ऑपरेटरों के लिए अलग टोकन का उपयोग करती हैं। VB.NET में, उदाहरण के लिए, =टोकन का उपयोग केवल अधिभारित समानता-चेक ऑपरेटर के लिए अभिव्यक्तियों के भीतर किया जाता है, और Isइसे संदर्भ-परीक्षण या अशक्त-परीक्षण ऑपरेटर के रूप में उपयोग किया जाता है। एक =प्रकार पर उपयोग करने के लिए जो समानता-जांच ऑपरेटर को ओवरराइड नहीं करता है, विफल हो जाएगा, जैसा कि Isसंदर्भ समानता या अशक्तता के परीक्षण के अलावा किसी भी उद्देश्य के लिए उपयोग करने का प्रयास करेगा ।

(*) प्रकार आम तौर पर केवल स्वयं के साथ तुलना के लिए समानता को अधिभारित करते हैं, लेकिन यह अन्य विशेष प्रकार की तुलना के लिए समानता ऑपरेटर को अधिभारित करने के प्रकारों के लिए उपयोगी हो सकता है; उदाहरण के लिए, int(और IMHO होना चाहिए था, लेकिन नहीं था) की तुलना के लिए एक समानता ऑपरेटरों को परिभाषित किया float, ताकि 16777217 खुद को 16777216f के बराबर रिपोर्ट न करे। यह है के रूप में, के बाद से इस तरह का कोई ऑपरेटर परिभाषित किया गया है, सी # को बढ़ावा देंगे intकरने के लिए float, 16777216f को यह गोलाई के समक्ष समानता की जांच ऑपरेटर इसे देखता है; फिर उस ऑपरेटर ने दो समान फ़्लोटिंग-पॉइंट नंबर देखे और उन्हें बराबर के रूप में रिपोर्ट किया, जो उस दौर की अनभिज्ञता थी।


एक अंतर-फ्लोट तुलना तुलना झूठी होने के बजाय, मैं उस दृष्टिकोण को पसंद करता हूं जो एफ # का उपयोग करता है, जो कि इस तरह की तुलना को बिल्कुल भी अस्वीकार करना है। तब प्रोग्रामर यह तय कर सकता है कि मूल्यों को अलग-अलग प्रकार का है या नहीं। क्योंकि कभी-कभी, आखिरकार, हम इसके3 बराबर होने का इलाज करना चाहते हैं 3.0f। यदि हमें प्रोग्रामर को यह कहने की आवश्यकता है कि हर मामले में क्या इरादा है, तो अनपेक्षित परिणामों के लिए डिफ़ॉल्ट व्यवहार का कोई खतरा नहीं है, क्योंकि कोई डिफ़ॉल्ट व्यवहार नहीं है।
फोगोग ph

@ फोग: मेरी निजी भावना यह है कि भाषाओं के पास समानता परीक्षण के अपने "सामान्य" साधन होने चाहिए, जो एक समतुल्य संबंध को लागू करते हैं, और उन सभी संचालनों के लिए मना करते हैं जिनके लिए यह नहीं होगा। मुझे पूर्णांक और फ़्लोट के बीच एक भाषा की जांच समानता होने का एक बड़ा फायदा नहीं दिखता है, यह पुष्टि करके कि एक फ्लोट ठीक एक पूरी संख्या का प्रतिनिधित्व करता है, जो इंट से मेल खाता है, बनाम बस ऐसी तुलना करने से मना करते हैं, लेकिन भाषा के प्रदर्शन के लिए बेहतर दृष्टिकोण पर विचार करेंगे। तुलना से पहले एक हानिपूर्ण रूपांतरण।
सुपरकैट

0

वास्तव में महान जवाब और उदाहरण!

मैं दोनों के बीच मूलभूत अंतर जोड़ना चाहूंगा,

ऑपरेटर जैसे कि ==बहुरूपी नहीं हैं, जबकि Equalsहै

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


-1

जब हम किसी वस्तु का निर्माण करते हैं तो वस्तु के दो भाग होते हैं एक सामग्री है और दूसरी उस सामग्री का संदर्भ है। ==सामग्री और संदर्भ दोनों की तुलना करता है; equals()केवल सामग्री की तुलना करता है

http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq


1
यह सच नहीं है। यदि aऔर bदोनों स्ट्रिंग संदर्भ हैं, तो इसका परिणाम इस a == bबात पर निर्भर नहीं करता है कि संदर्भ एक ही वस्तु को इंगित करते हैं या नहीं।
फोगोग ph

-2

==

== ऑपरेटर का उपयोग किसी भी प्रकार के दो चर की तुलना करने के लिए किया जा सकता है, और यह बस बिट्स की तुलना करता है

int a = 3;
byte b = 3;
if (a == b) { // true }

नोट: इंट के बाईं ओर अधिक शून्य हैं लेकिन हम यहां इसकी परवाह नहीं करते हैं।

int (00000011) == बाइट b (00000011)

याद रखें == ऑपरेटर केवल चर में बिट्स के पैटर्न के बारे में परवाह करता है।

उपयोग == यदि दो संदर्भ (आदिम) ढेर पर एक ही वस्तु को संदर्भित करते हैं।

नियम वही हैं चाहे चर संदर्भ या आदिम हो।

Foo a = new Foo();
Foo b = new Foo();
Foo c = a;

if (a == b) { // false }
if (a == c) { // true }
if (b == c) { // false }

a == c सच है a == b गलत है

बिट पैटर्न a और c के लिए समान हैं, इसलिए वे == का उपयोग करने के बराबर हैं।

बराबरी का():

बराबरी () विधि का उपयोग करके देखें कि दो अलग-अलग वस्तुएं समान हैं या नहीं

जैसे कि दो अलग-अलग स्ट्रिंग ऑब्जेक्ट्स जो दोनों "जेन" में पात्रों का प्रतिनिधित्व करते हैं


2
यह गलत है। निम्नलिखित पर विचार करें object a = 3; object b = 3; Console.WriteLine(a == b);:। आउटपुट झूठा है, भले ही मूल्यों के बिट पैटर्न समान हैं। ऑपरेंड के प्रकार भी मायने रखते हैं। आपके उदाहरण में शून्य की भिन्न संख्या के बारे में हम "परवाह नहीं करते" कारण यह है कि जब तक हम बराबर ऑपरेटर को कॉल करते हैं, तब तक शून्य रूपांतरण की संख्या वास्तव में समान होती है , क्योंकि अंतर्निहित रूपांतरण के कारण।
फोगोग ph

-2

इक्वल और == के बीच एकमात्र अंतर ऑब्जेक्ट प्रकार की तुलना पर है। अन्य मामलों में, जैसे संदर्भ प्रकार और मूल्य प्रकार, वे लगभग समान हैं (या तो दोनों बिट-वार समानता हैं या दोनों संदर्भ समानताएं हैं)।

ऑब्जेक्ट: बराबर: बिट-वार समानता ==: संदर्भ समानता

स्ट्रिंग: (बराबर और == स्ट्रिंग के लिए समान हैं, लेकिन यदि स्ट्रिंग में से एक को वस्तु में बदल दिया जाता है, तो तुलना परिणाम अलग होगा) बराबर: बिट-वार समानता ==: बिट-वार समानता

अधिक स्पष्टीकरण के लिए यहां देखें ।


Object.Equals जरूरी नहीं कि बिटवाइज समानता को देखें। यह एक आभासी तरीका है, और एक ओवरराइड जो चाहे कर सकता है।
फोगोग ph

हां, आप सही हैं, आप इसे ओवरराइड करना चाहते हैं। लेकिन हम जिस विषय पर बात कर रहे हैं वह डिफ़ॉल्ट कार्यान्वयन है। Object.Equals का डिफ़ॉल्ट कार्यान्वयन बिट-वार समानता है।
विल यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.