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

0

型の 2 つのインスタンスが等しい参照であるかどうか (つまり、それらが同じメモリ アドレスを参照しているかどうか) をチェックするのは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)2 番目の as の代わりに を使用すると、無限再帰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 であることを確認します。参照値を「null」オブジェクト参照と比較し、両方が null に等しい場合は等しく、True を返します。

最初のオブジェクトだけが null で、2 番目のオブジェクトがそうでない場合は、false を返します。

最後に、最初の Shop オブジェクトが null でない場合、コードは 2 番目のオブジェクトが null ではないと想定し、それらのインスタンスを Shop オブジェクトと比較して、それらが等しいことを確認します。

そして、null オブジェクトを比較するためにこの方法を使用しなければならない主な理由は、null またはインスタンス化されていないオブジェクトを比較すると実行時エラーが発生するため、デフォルトの "==" 演算子をこの方法でオーバーライドする必要があるためです。

于 2016-01-12T06:24:49.637 に答える