2016-01-12 24 views
19

Ai đó có thể giải thích cho tôi tình trạng quá tải này có nghĩa là gì?Quá tải này có nghĩa là gì?

public static bool operator ==(Shop lhs, Shop rhs) 
{ 
    if (Object.ReferenceEquals(lhs, null)) 
    { 
     if (Object.ReferenceEquals(rhs, null)) 
     { 
      return true; 
     } 
     return false; 
    } 

    return lhs.Equals(rhs); 
} 

Tôi chưa bao giờ thấy Object.ReferenceEquals trong tình trạng quá tải

+5

'Object này. ReferenceEquals' kiểm tra nếu các tham chiếu bằng nhau ...;) - Nói cách khác, nó sẽ kiểm tra nếu đối tượng là đối tượng chính xác * *, về mặt vật lý m địa chỉ emory. – Rob

+0

Có thể trùng lặp của [C# .Equals(), .ReferenceEquals() và == toán tử] (http://stackoverflow.com/questions/3869601/c-sharp-equals-referenceequals-and-operator) – Rohit

+4

Kể từ khi == toán tử của lớp Shop bị quá tải, mã sẽ tránh sử dụng nó để kiểm tra tham số cho tham chiếu null. nếu (lhs == null) sẽ gây ra một đệ quy vô hạn và ứng dụng sẽ chỉ đơn giản là sụp đổ với một ngoại lệ tràn ngăn xếp. –

Trả lời

37

quá tải này được dự định để so sánh hai trường hợp của Shop. Nó sử dụng Object.ReferenceEquals để xác định xem một trong các phiên bản có phải là null hay không.
Không thể sử dụng lhs == null hoặc rhs == null, vì điều này một lần nữa sẽ gọi số operator == và tạo một lần đệ quy vô hạn dẫn đến StackOverflowException.

Nếu cả hai trường hợp là null thì trả về đúng (vì chúng bằng nhau).
Nếu chỉ một trường hợp là null, nó sẽ trả về false (vì chúng không bằng nhau).
Nếu cả hai trường hợp không phải là null, nó trả về kết quả của việc thực hiện EqualsShop.

+4

bạn cũng có thể gọi '(đối tượng) lhs == null' và' (đối tượng) rhs == null' cho cùng một hiệu ứng – slawekwin

-8

Rất dễ dàng. "NULL" thực sự là một đối tượng nằm trong bộ nhớ và có tham chiếu và có thể được đặt thành bất kỳ đối tượng nào là lớp con của lớp "Đối tượng" cơ sở. Vì vậy, ở trên mã đầu tiên kiểm tra cả hai "Shop" đối tượng là bằng nhau null bằng cách so sánh giá trị tham chiếu của họ để tham khảo đối tượng "null", nếu cả hai đều bằng null để họ bằng nhau và trả về True.

Nếu đối tượng đầu tiên là null và không phải là đối tượng thứ hai, trả về false.

Và cuối cùng nếu đối tượng cửa hàng đầu tiên không phải là rỗng thì mã giả định rằng đối tượng thứ hai không phải là rỗng và so sánh đối tượng của chúng với đối tượng cửa hàng để kiểm tra chúng bằng nhau.

Và lý do chính chúng tôi sử dụng cách này để so sánh đối tượng null là vì bạn gặp lỗi thời gian chạy nếu bạn so sánh đối tượng không được hiển thị hoặc không phải do đó chúng tôi cần ghi đè toán tử "==" mặc định theo cách này.

+14

Vỏ của bạn là rất khó chịu, tôi cũng không chắc chắn nếu _ "'NULL' Thực sự là một đối tượng nằm trong Memory "_ là cách chính xác để suy nghĩ về nó – MickyD

+0

Trong trường hợp Shop là một cấu trúc (ValueType) Chúng ta có thể định nghĩa chúng là Nullable Type (Nullable ) Vì vậy, trong trường hợp này chúng có thể được như vậy. – Waxoft

+0

Cuối cùng (nếu Object.ReferenceEquals (lhs, null) (Kiểm tra, lhs có tham chiếu đến bất kỳ đối tượng nào và nếu nó không tham chiếu đến bất kỳ đối tượng nào thì nếu đúng. – Waxoft

0

Nó là một operator overload (của ==, không phương pháp quá tải của ReferenceEquals) để kiểm tra xem hai trường hợp của loại Shop là tài liệu tham khảo tương đương (có nghĩa là, cho dù họ đề cập đến cùng địa chỉ bộ nhớ).

bool result = shop1 == shop2; //shop1 and shop2 are of type Shop 

Khi tuyên bố == điều hành, bạn cũng sẽ được yêu cầu phải quá tải phù hợp của nó (hoặc truy cập) điều hành !=:

public static bool operator ==(Shop lhs, Shop rhs) { 
    if (Object.ReferenceEquals(lhs, null)) { //Check if the left-hand-side Shop is null 
     if (Object.ReferenceEquals(rhs, null)) { 
      return true; //both are null, equal reference 
     } 
     return false; //lhs is null, but rhs is not (not equal reference) 
    } 
    return lhs.Equals(rhs); //lhs is not null, thus can call .Equals, check if it is Equals to rhs 
} 

public static bool operator !=(Shop lhs, Shop rhs) { //the opposite operator 
    if (Object.ReferenceEquals(lhs, null)) { 
     if (Object.ReferenceEquals(rhs, null)) { 
      return false; 
     } 
     return true; 
    } 
    return !lhs.Equals(rhs); 
} 

Nó cũng đáng để lưu ý rằng Object.ReferenceEquals(lhs, null) được sử dụng thay vì lhs == null như thứ hai sẽ dẫn đến tình trạng quá tải khác == được gọi đến infinite recursion gây ra StackOverflowException.

Chúng được sử dụng như thế này:

Shop shop1 = new Shop(); 
Shop shop2 = new Shop(); 
bool result = shop1 == shop2; //this will return false, since lhs and rhs referring to two different memory address 
shop2 = shop1; 
result = shop1 == shop2; //this will return true, referring to the same memory location 
shop1 = null; 
shop2 = null; 
result = shop1 == shop2; //this will return true, both are null 

Hiểu được điều này, bạn thậm chí có thể tạo ra một cái gì đó như thế này:

public struct MyCrazyInt{ //this will reverse the result of + and - 
    private int Value { get; set; } 
    public MyCrazyInt(int value) :this() { 
     Value = value; 
    } 

    public bool Equals(MyCrazyInt otherCrazy) { 
     return this.Value != otherCrazy.Value; //reverse this result 
    } 

    public static MyCrazyInt operator +(MyCrazyInt lhs, MyCrazyInt rhs) { 
     int lhsVal = lhs.Value; 
     int rhsVal = rhs.Value; 
     return new MyCrazyInt(lhsVal - rhsVal); //note that direct lhs-rhs will cause StackOverflow 
    } 

    public static MyCrazyInt operator -(MyCrazyInt lhs, MyCrazyInt rhs) { 
     int lhsVal = lhs.Value; 
     int rhsVal = rhs.Value; 
     return new MyCrazyInt(lhsVal + rhsVal); //note that direct lhs+rhs will cause StackOverflow 
    } 

    public override string ToString() { 
     return Value.ToString(); 
    } 
} 

Và sau đó sử dụng nó như

MyCrazyInt crazyInt1 = new MyCrazyInt(5); 
MyCrazyInt crazyInt2 = new MyCrazyInt(3); 
MyCrazyInt crazyInt3 = crazyInt1 - crazyInt2; //this will return 8 
crazyInt3 = crazyInt1 + crazyInt2; //this will return 2 
Các vấn đề liên quan