Что означает эта перегрузка?
Может кто-нибудь объяснить мне, что означает эта перегрузка?
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 в перегрузке
Ответы
Ответ 1
Эта перегрузка была предназначена для сравнения двух экземпляров Shop
. Он использует Object.ReferenceEquals
, чтобы определить, является ли один из экземпляров null
.
Он не может использовать lhs == null
или rhs == null
, потому что это снова вызовет operator ==
и создаст бесконечную рекурсию, ведущую к StackOverflowException
.
Если оба экземпляра null
, он возвращает true (поскольку они равны).
Если только один экземпляр null
, он возвращает false (поскольку они не равны).
Если оба экземпляра не являются null
, он возвращает результат реализации Equals
Shop
.
Ответ 2
Это operator overload
(of ==, not method 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
, поскольку второй приведет к тому, что другая перегрузка ==
будет вызвана до бесконечной рекурсии который вызывает 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
Ответ 3
Это очень легко.
"NULL" фактически является объектом, который находится в памяти и имеет ссылку, и может быть установлен для любого объекта. Это подкласс класса Base "Object".
Таким образом, выше кода сначала проверяет, что оба объекта "Магазин" равны нулю, сравнивая их ссылочное значение с ссылкой на объект "null", если оба они равны нулю, поэтому они равны и возвращают True.
Если только первый объект имеет значение null, а второй - нет, верните false.
И, наконец, если первый объект Shop не равен null, код предполагает, что второй не является нулевым и сравнивает их экземпляр с объектом Shop, чтобы проверить, что они равны.
И основная причина, по которой мы используем этот способ для сравнения нулевого объекта, заключается в том, что вы получаете ошибку времени выполнения, если вы сравниваете объект с нулевым или не созданным экземпляром, поэтому нам необходимо переопределить оператор по умолчанию "==" таким образом.