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 过载

4

3 回答 3

37

此重载旨在比较Shop. 它用于Object.ReferenceEquals确定其中一个实例是否为null.
它不能使用lhs == nullor rhs == null,因为这会再次调用 theoperator ==并创建一个无限递归导致 a StackOverflowException

如果两个实例都null返回 true(因为它们相等)。
如果只有一个实例,null则返回 false(因为它们不相等)。
如果两个实例都不是,null则返回Equals.Shop

于 2016-01-12T06:08:54.220 回答
0

检查两个类型的实例是否具有相同的引用(即它们是否引用相同的内存地址)是一个operator overload(==,而不是方法重载)。ReferenceEqualsShop

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
于 2016-01-12T15:47:30.033 回答
-8

这很容易。“NULL”实际上是一个驻留在内存中的对象,具有引用,可以设置为任何对象,它是基“对象”类的子类。

因此,上面的代码首先通过将两个“Shop”对象的引用值与“null”对象引用进行比较来检查两个“Shop”对象是否相等,如果它们都等于null,那么它们相等并返回True。

如果只有第一个对象是 null 而第二个不是,则返回 false。

最后,如果第一个 Shop 对象不为空,则代码假定第二个不为空,并将它们的实例与 Shop 对象进行比较以检查它们是否相等。

我们必须使用这种方式来比较 null 对象的主要原因是,如果您比较 null 或未实例化的对象,则会出现运行时错误,因此我们需要以这种方式覆盖默认的“==”运算符。

于 2016-01-12T06:24:49.637 回答