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

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

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 в перегрузке


person Madness    schedule 12.01.2016    source источник
comment
Object.ReferenceEquals проверяет, равны ли ссылки ...;) - Другими словами, он проверяет, является ли объект тем же самым объектом с точки зрения адреса физической памяти.   -  person Rob    schedule 12.01.2016
comment
Возможный дубликат оператора C # .Equals (), .ReferenceEquals () и ==   -  person Rohit    schedule 12.01.2016
comment
Поскольку оператор == класса Shop перегружен, код избегает его использования для проверки параметров на пустую ссылку. if (lhs == null) вызовет бесконечную рекурсию, и приложение просто вылетит из-за исключения переполнения стека.   -  person Oguz Ozgul    schedule 12.01.2016
comment
Возможный дубликат оператора переопределения ==. Как сравнить с нулем?   -  person choz    schedule 12.01.2016
comment
Это не перегрузка. Перегрузка будет, если вы определили другой ReferenceEquals с другими типами аргументов. (В этом случае это было бы плохой идеей, но полезно с другими методами).   -  person Jon Hanna    schedule 12.01.2016


Ответы (3)


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

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

person René Vogt    schedule 12.01.2016
comment
вы также можете вызвать (object)lhs == null и (object)rhs == null для того же эффекта - person slawekwin; 12.01.2016

Это operator overload (==, а не перегрузка метода 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, поскольку второй вызовет еще одну перегрузку == до бесконечная рекурсия, которая вызывает StackOverflowException.

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

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

А затем используйте это так

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
person Ian    schedule 12.01.2016

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

Итак, приведенный выше код сначала проверяет, что оба объекта «Магазин» равны нулю, сравнивая их ссылочное значение с «нулевой» ссылкой на объект, если оба они равны нулю, то есть они равны, и возвращают Истину.

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

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

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

person Waxoft    schedule 12.01.2016
comment
Ваш корпус очень раздражает, также я не уверен, что 'NULL' На самом деле является объектом, который находится в памяти, - это правильный способ думать об этом - person MickyD; 12.01.2016
comment
В случае, если Shop является структурой (ValueType), мы можем определить их как Nullable Type (Nullable ‹T›). В этом случае они могут быть такими. - person Waxoft; 12.01.2016
comment
Наконец (если Object.ReferenceEquals (lhs, null) (Проверить, ссылается ли lhs на какой-либо объект, и если он не ссылается ни на какой объект, то если это правда. - person Waxoft; 12.01.2016