String.Equals (a, b) StackOverflowException कैसे उत्पन्न नहीं करता है?


159

String ==ऑपरेटर की जांच करते समय , मैंने देखा कि यह कॉल करता है String.Equals(string a, string b), जिसका अर्थ है कि यह केवल एक पास-थ्रू है।

String.Equals(string a, string b)विधि की जांच करते हुए , मैं देखता हूं कि यह ==ऑपरेटर का उपयोग करके एक समानता की जांच करता है । यह वास्तव में कैसे काम कर रहा है और StackOverflowExceptionजब ऐसा कुछ कर रहा है "x" == "x"या नहीं कर रहा है "x" == "y"?

अद्यतन : मैंने JetBrains को बताया और उन्होंने इसे dotPeek के लिए एक महत्वपूर्ण प्राथमिकता बना दिया। https://youtrack.jetbrains.com/issue/DOTP-6789

मैंने ILSpy के GitHub रेपो पर एक मुद्दा भी जोड़ा।

स्ट्रिंग समानता


नि: शुल्क नेट परावर्तक (v6) प्रदर्शित करता है यह "गलत" सी # (यह सिर्फ शो IE में a == b), लेकिन सही VB.NET में: a Is b
मार्क हर्ड

जवाबों:


217

आपके डिकम्पॉइलर में एक बग है। असली कोड चेक नहीं करता है a == b, यह चेक करता है (Object)a == (Object)b, ओवरलोड ऑपरेटर को दरकिनार करता है ।


4
@Aravol सच है, लेकिन स्रोत केवल हाल ही में जारी किया गया है
डस्टिन डेविस

2
हालांकि यह किसी भी मामले में बहुत ही अस्पष्ट कोड है। एक सरल object.ReferenceEquals(a,b)बहुत स्पष्ट हो जाएगा ..
Voo

1
@ क्या मैं तर्क दूंगा कि वर्तमान संस्करण स्पष्ट है। आपको object.ReferenceEqualsकास्ट संस्करण के साथ कुछ भी जानने की आवश्यकता नहीं है (उदाहरण के लिए, अगर क्या aहै null?), और, जब तक आप जानते हैं कि कास्टिंग क्या है, यह निश्चित रूप से बाधित नहीं है।
wchargin

72
"आपके डिकम्पॉइलर में एक बग है"। माइक गिराता है।
एस्पिनची

1
@Voo मेरा अनुमान है: MS समान रूप से पठनीय है (Object)a == (Object)bऔर Object.ReferenceEquals(a, b)इसके बारे में विचार करता है , लेकिन यह मुझे आश्चर्यचकित नहीं करेगा Object.ReferenceEquals(a, b)अगर अधिकतम इनलाइन गहराई तक पहुंचने पर बस इनबिल्ट न होने का थोड़ा सा भी मौका हो। MS बहुत सारे माइक्रो-ऑप्टिमाइज़ेशन करता है, क्योंकि उपयोगकर्ता कोड में अधिकांश तंग छोरों को MS कोड कहते हैं।

50

यहाँ Microsoft से वास्तविक कोड है। ऑपरेटर ==है कार्यान्वित एक रों

public static bool operator == (String a, String b) {
   return String.Equals(a, b);
}

ऑपरेटर ==कॉल String.Equals जो के रूप में कार्यान्वित किया जाता है:

public static bool Equals(String a, String b) {
    if ((Object)a==(Object)b) {
        return true;
    }

    if ((Object)a==null || (Object)b==null) {
        return false;
    }

    if (a.Length != b.Length)
        return false;

    return EqualsHelper(a, b);
}

जैसा कि आप देख रहे हैं, स्ट्रिंग की if ((Object)a==(Object)b)कास्टिंग objectऔर फिर तुलना करने के लिए स्ट्रिंग समानता का उपयोग किया जाता है । तो यह ==स्ट्रिंग क्लास में ओवरलोड ऑपरेटर को नहीं बुलाएगा ।

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