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

ฉันยังเพิ่มปัญหาใน repo ของ GSpub ของ ILSpy อีกด้วย

ความเท่าเทียมกันของสตริง


ฟรี .NET สะท้อน (v6) แสดงว่า "ผิด" ใน C # (IE มันก็แสดงให้เห็นa == b) แต่ที่ถูกต้องใน a Is bVB.NET:
Mark Hurd

คำตอบ:


217

Decompiler ของคุณมีข้อบกพร่อง รหัสจริงไม่ได้ตรวจa == bสอบตรวจสอบ(Object)a == (Object)bผ่านตัวดำเนินการที่โอเวอร์โหลด


4
@Avol จริง แต่แหล่งได้รับการปล่อยตัวเมื่อเร็ว ๆ นี้
ดัสตินเดวิส

2
มันเป็นรหัสที่ยุ่งเหยิงไม่ว่าในกรณีใด ๆ ง่ายobject.ReferenceEquals(a,b)จะชัดเจนมากขึ้น ..
Voo

1
@Voo ฉันจะยืนยันว่ารุ่นปัจจุบันชัดเจนขึ้น คุณไม่จำเป็นต้องรู้อะไรเกี่ยวobject.ReferenceEqualsกับรุ่นนักแสดง (เช่นaจะเกิดnullอะไรขึ้น?) และตราบใดที่คุณรู้ว่าการคัดเลือกนักแสดงคืออะไร
wchargin

72
"Decompiler ของคุณมีบั๊ก" หยดไมค์
espinchi

1
@ Voo ของฉันเดา: MS พิจารณา(Object)a == (Object)bและObject.ReferenceEquals(a, b)อ่านอย่างเท่าเทียมกัน แต่มันจะไม่แปลกใจฉันถ้าObject.ReferenceEquals(a, b)เพียงแค่มีโอกาสเล็กน้อยที่จะไม่ได้รับการ inline ถ้าถึงความลึกแบบอินไลน์สูงสุดถึง MS ทำการเพิ่มประสิทธิภาพไมโครมากเนื่องจากลูปที่แน่นที่สุดในรหัสผู้ใช้จะเรียกรหัส MS

50

นี่คือรหัสจริงจาก Microsoft ผู้ประกอบการ==จะดำเนินการ s

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แล้วทำการเปรียบเทียบ ดังนั้นสิ่งนี้จะไม่เรียกตัวดำเนินการที่โอเวอร์โหลด==ในคลาสสตริง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.