简体   繁体   中英

What does this overload mean?

Can someone explain me what does this overload mean?

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

I have never seen Object.ReferenceEquals in overload

This overload was intended to compare two instances of Shop . It uses Object.ReferenceEquals to determine if one of the instances is null .
It cannot use lhs == null or rhs == null , because this would again invoke the operator == and create an infinite recursion leading to a StackOverflowException .

If both instances are null it returns true (since they are equal).
If only one instance is null it returns false (since they are not equal).
If both instances are not null it returns the result of the Equals implementation of Shop .

It is an operator overload (of ==, not method overload of ReferenceEquals ) to check if two instances of type Shop is of equal reference (that is, whether they refer to the same memory address ).

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

When declaring == operator, you will also be required to overload its matching (or counter) operator != :

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

It is also worth to note that Object.ReferenceEquals(lhs, null) is used instead of lhs == null as the second will lead to another overload == being called till infinite recursion which causes StackOverflowException .

They are used like this:

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

Understanding this, you could even create something like this:

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

And then use it like this

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

It's very easy. "NULL" actually is an object that resides in memory and has a reference and can be set To any object That is a subclass of Base "Object" class.

So above code first checks both "Shop" objects are equally null by comparing their reference value to "null" object reference, if both of them are equal to null so they are equal and return True.

If just first object is null and second one is not, return false.

And finally if first Shop object is not null then the code supposes that the second one is not null and compares their instance against Shop object to check they are equal.

And the main reason we nust use this way to compare null object is because you get a runtime error if you compare null or not instantiated object so we need to override the default "==" operator in this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM