2016-01-12 2 views
19

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

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

+5

'Object. ReferenceEquals' проверяет, равны ли ссылки ...;) - Другими словами, он проверяет, является ли объект * точно таким же объектом *, в терминах физического m emory адрес. – Rob

+0

Возможный дубликат [C# .Equals(), .ReferenceEquals() и == operator] (http://stackoverflow.com/questions/3869601/c-sharp-equals-referenceequals-and-operator) – Rohit

+4

Поскольку == оператор класса Shop перегружен, код избегает его использования для проверки параметров для нулевой ссылки. if (lhs == null) приведет к бесконечной рекурсии, и приложение просто потерпит крах при исключении переполнения стека. –

ответ

37

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

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

+4

вы также можете вызвать '(object) lhs == null' и' (object) rhs == null' за тот же эффект – slawekwin

-8

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

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

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

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

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

+14

Ваш корпус очень раздражает, также я не уверен, если _ "NULL 'На самом деле это объект, который находится в памяти "_ - это правильный способ думать об этом – MickyD

+0

В случае, если Shop является структурой (ValueType), мы можем определить их как Nullable Type (Nullable ). Так что в этом случае они могут быть такими. – Waxoft

+0

И наконец (если Object.ReferenceEquals (lhs, null) (Проверить, ссылается ли lhs на какой-либо объект, и если он не ссылается ни на какой-либо объект, то if is true. – Waxoft

0

Это 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 как второй приведет к другой перегрузке ==, вызываемой до infinite recursion, которая вызывает 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 
Смежные вопросы