0

私はC#で平等を探していて、この行に沿って何かを実装していました:

public class MyType
{
    public string MyProperty { get; set; }

    public MyType(string myProperty)
    {
        MyProperty = myProperty;
    }

    protected bool Equals(MyType other)
    {
        Console.WriteLine("I'm calling the MyType.Equals override");
        return MyProperty == other.MyProperty;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((MyType) obj);
    }

    public override int GetHashCode()
    {
        throw new NotImplementedException();
    }

    public static bool operator ==(MyType lhs, MyType rhs)
    {
        return Equals(lhs, rhs);
    }

    public static bool operator !=(MyType lhs, MyType rhs)
    {
        return !(lhs == rhs);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var type1 = new MyType("test");
        var type2 = new MyType("test");

        Console.WriteLine($"type1 == type2 => {type1 == type2}");
        Console.Read();
    }
}

そして出力は

MyType.Equals オーバーライド
type1 == type2 => Trueを呼び出しています

このように等値演算子をオーバーライドすることによって生じる可能性のある驚きを十分に認識していますが、知りたいのは、インスタンスの仮想メソッド (protected bool Equals(MyType other) in MyType ) を呼び出すことができる理由です。クラス) 静的メソッドから。
わかりました、実際には静的メソッドのようには見えません。

オペレーター

キーワードですが、私が知る限り、IL では静的メソッドとして変換されます。

.method public hidebysig specialname static bool  op_Equality(class MyType lhs, class MyType rhs) cil managed

object.Equals 静的メソッド呼び出しのどこかで魔法が発生すると思われますが、実際にどのように機能するかはわかりません。光を当ててみませんか?

4

3 に答える 3

1

魔法はありません。同様のコードを自分でうまく実装できます。 Object.Equal(object,object)最終的に使用する呼び出しにより、表示されるleft.Equals(right)結果が生成されます。

2 つのオブジェクトが同じオブジェクト参照を表さず、どちらも null でない場合、objA.Equals(objB) を呼び出して結果を返します。つまり、objA が Object.Equals(Object) メソッドをオーバーライドすると、このオーバーライドが呼び出されます。

public static bool operator ==(MyType lhs, MyType rhs)
{
    return Equals(lhs, rhs); // calls Object.Equal(object,object)
}

コードは、次のインライン実装とほぼ同等です。

public static bool operator ==(MyType lhs, MyType rhs)
{
    if (lhs == null || lhs == null) 
    {
        // this branch is not executed in your sample
        return RefrenceEquals(lhs,rhs);
    } 
    return lhs.Equal(rhs); // calls override bool Equals(object obj)
    // which in turn calls 
    // bool Equals(MyType other) since both are other is not null
}
于 2016-08-23T06:11:06.970 に答える
1

魔法は一切必要ありません。Equalsメソッドは仮想オンであり、objectそれをオーバーライドしています-したがって、を呼び出す((object)lhs).Equalsと、もちろんオーバーライドされたメソッドが呼び出されます。そして、それobject.Equalsはあなたが呼び出している static が行うことです:) 他の場所で呼び出しても同じことが起こりますEquals。演算子は実際には単なる静的メソッドです。

于 2016-08-23T06:17:52.787 に答える