Làm thế nào để String.Equals (a, b) không tạo ra StackOverflowException?


159

Trong khi kiểm tra String ==toán tử, tôi nhận thấy rằng nó gọi String.Equals(string a, string b), nghĩa là nó chỉ là một giao dịch.

Kiểm tra String.Equals(string a, string b)phương thức, tôi thấy rằng nó thực hiện kiểm tra đẳng thức bằng cách sử dụng ==toán tử. Làm thế nào điều này thực sự hoạt động và không gây ra StackOverflowExceptionkhi làm một cái gì đó như "x" == "x"hoặc "x" == "y"?

Cập nhật : Tôi cho JetBrains biết và họ ưu tiên cho dotPeek. https://youtrack.jetbrains.com/su/DOTP-6789

Tôi cũng đã thêm một vấn đề trên repo GitHub của ILSpy.

Chuỗi bình đẳng


.NET Reflector miễn phí (v6) hiển thị "sai" trong C # (nghĩa là nó chỉ hiển thị a == b), nhưng chính xác trong VB.NET : a Is b.
Đánh dấu Hurd

Câu trả lời:


217

Trình dịch ngược của bạn có lỗi. thực không kiểm tra a == b, nó kiểm tra (Object)a == (Object)b, bỏ qua toán tử quá tải.


4
@Aravol đúng, nhưng nguồn chỉ mới được phát hành gần đây
Dustin Davis

2
Đó là mã khá khó hiểu trong mọi trường hợp. Một đơn giản object.ReferenceEquals(a,b)sẽ rõ ràng hơn nhiều ..
Voo

1
@Voo Tôi cho rằng phiên bản hiện tại rõ ràng hơn. Bạn không cần biết bất cứ điều gì về object.ReferenceEqualsphiên bản diễn viên (ví dụ: nếu anullgì?), Và, miễn là bạn biết diễn viên là gì, chắc chắn nó không bị xáo trộn.
wchargein

72
"Trình dịch ngược của bạn có lỗi". Làm rơi mic.
đặc biệt là

1
@Voo Dự đoán của tôi: MS cân nhắc (Object)a == (Object)bObject.ReferenceEquals(a, b)có thể đọc được như nhau, nhưng sẽ không làm tôi ngạc nhiên nếu Object.ReferenceEquals(a, b)chỉ có một cơ hội nhỏ để không bị nội tuyến nếu đạt được độ sâu nội tuyến tối đa. MS thực hiện rất nhiều tối ưu hóa vi mô, vì hầu hết các vòng lặp chặt chẽ trong mã người dùng cuối cùng đều gọi mã MS.

50

Đây là mã thực sự từ Microsoft. Toán tử ==được thực hiện một s

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

==các cuộc gọi toán tử String.Equals được thực hiện như:

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);
}

Như bạn thấy, việc so sánh cho đẳng thức chuỗi được thực hiện bằng cách sử dụng if ((Object)a==(Object)b)truyền chuỗi đến objectvà sau đó thực hiện so sánh. Vì vậy, điều này sẽ không gọi toán tử quá tải ==trong lớp chuỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.