Что означает эта перегрузка?

Может кто-нибудь объяснить мне, что означает эта перегрузка?

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

Я никогда не видел Object.ReferenceEquals в перегрузке

3 ответа

Эта перегрузка была предназначена для сравнения двух случаев Shop, Оно использует Object.ReferenceEquals определить, является ли один из экземпляров null,
Не может использовать lhs == null или же rhs == nullпотому что это снова вызовет operator == и создать бесконечную рекурсию, ведущую к StackruException,

Если оба экземпляра null он возвращает истину (так как они равны).
Если только один экземпляр null возвращает false (поскольку они не равны).
Если оба экземпляра не null он возвращает результат Equals реализация Shop,

Это operator overload (of ==, не перегрузка метода ReferenceEquals) чтобы проверить, если два экземпляра типа Shop имеет равные ссылки (то есть, ссылаются ли они на один и тот же адрес памяти).

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

При объявлении == оператор, вам также потребуется перегрузить его соответствующий (или счетчик) оператор !=:

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

Также стоит отметить, что Object.ReferenceEquals(lhs, null) используется вместо lhs == null а вторая приведет к очередной перегрузке == вызывается до бесконечной рекурсии, которая вызывает StackruException,

Они используются так:

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

Понимая это, вы могли бы даже создать что-то вроде этого:

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 Stackru
    }

    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 Stackru
    }

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

А потом использовать это так

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

Это очень просто. "NULL" на самом деле является объектом, который находится в памяти и имеет ссылку и может быть установлен на любой объект, который является подклассом базового класса "Object".

Таким образом, приведенный выше код сначала проверяет, что оба объекта "Магазин" одинаково равны нулю, сравнивая их ссылочное значение с "нулевой" ссылкой на объект, если оба они равны нулю, поэтому они равны и возвращают True.

Если только первый объект имеет значение null, а второй - нет, верните false.

И, наконец, если первый объект Shop не равен NULL, тогда код предполагает, что второй объект не равен NULL, и сравнивает их экземпляр с объектом Shop, чтобы проверить, что они равны.

И главная причина, по которой мы должны использовать этот способ для сравнения нулевого объекта, заключается в том, что вы получаете ошибку времени выполнения, если сравниваете нулевой или не экземплярный объект, поэтому нам нужно переопределить оператор "==" по умолчанию таким образом.

Другие вопросы по тегам