2011-08-07 35 views
5

Sử dụng Reflector hoặc DotPeek, việc thực hiện System.Linq.Data.Binary của sự quá tải toán tử bằng trông như thế này:Tham khảo điều hành bình đẳng trong thực hiện điều hành bình đẳng

[Serializable, DataContract] 
public sealed class Binary : IEquatable<Binary> 
{ 
... 
    public static bool operator ==(Binary binary1, Binary binary2) 
    { 
     return ((binary1 == binary2) || (((binary1 == null) && (binary2 == null)) || (((binary1 != null) && (binary2 != null)) && binary1.EqualsTo(binary2)))); 
    } 

tôi phải mất một cái gì đó rõ ràng, hoặc có một cơ chế diễn ra mà tôi không biết (chẳng hạn như ngầm gọi đối tượng == trong cơ thể?). Tôi thừa nhận, tôi hiếm khi cần phải quá tải các nhà khai thác tiêu chuẩn.

Tại sao việc triển khai này không dẫn đến việc đệ quy vô hạn (một thử nghiệm đơn giản cho thấy nó không recurse vô hạn)? Biểu thức điều kiện đầu tiên là binary1 == binary2, bên trong việc thực hiện quá tải của toán tử sẽ được gọi nếu bạn sử dụng binary1 == binary2 bên ngoài việc thực hiện, và tôi cũng nghĩ rằng, bên trong là tốt.

Trả lời

5

Tôi mong đợi đây là lỗi trong trình biên dịch ngược của bạn. Redgate Reflector có/có lỗi tương tự, và tôi cũng có found it in ILSpy.

Lý do tại sao điều này khó có thể dịch ngược là vì nó kiểm tra một cách tinh tế các quy tắc quá tải C#. Mã gốc có nhiều khả năng giống như (object)obj1==(object)obj2, nhưng chuyển đổi này không thể được nhìn thấy trong chính IL. Việc truyền bất kỳ kiểu tham chiếu nào đến một kiểu cơ sở là một no-op khi mà thời gian chạy có liên quan. Tuy nhiên nó nhận được C# để chọn các opcodes bình đẳng tham chiếu thay vì gọi các toán tử đẳng thức quá tải.

IMO cách chính xác để thực hiện điều này trong trình dịch ngược là luôn luôn dịch ngược bình đẳng tham chiếu sang (object)obj1==(object)obj2 và sau đó tối ưu hóa phôi dự phòng nếu chúng không ảnh hưởng đến độ phân giải quá tải. Cách tiếp cận này cũng sẽ khắc phục các vấn đề tương tự với quá tải phương thức.

2

Rõ ràng là một lỗi trong phiên bản ReSharper của bạn (và dotpeek). Phiên bản 6.0 (6.0.2202.688) của ReSharper thực hiện chính xác:

public static bool operator ==(Binary binary1, Binary binary2) { 
     if ((object)binary1 == (object)binary2) 
      return true; 
     if ((object)binary1 == null && (object)binary2 == null) 
      return true; 
     if ((object)binary1 == null || (object)binary2 == null) 
      return false; 
     return binary1.EqualsTo(binary2); 
    } 
+2

Xin lỗi, tôi có nghĩa là để nói Reflector, không Resharper trong bài viết của tôi (mà tôi đã sửa). Thú vị là Resharper hiện tại đã làm đúng, nhưng DotPeek (bởi cùng một công ty) thì không. – hatchet

Các vấn đề liên quan