web-dev-qa-db-ja.com

演算子のオーバーロード==、!=、等しい

私はすでに question を経験しました

_==_、_!=_およびEquals()を実装する必要があることを理解しています。

_public class BOX
{
    double height, length, breadth;

    // this is first one '=='
    public static bool operator== (BOX obj1, BOX obj2)
    {
        return (obj1.length == obj2.length 
                    && obj1.breadth == obj2.breadth 
                    && obj1.height == obj2.height);
    }

    // this is second one '!='
    public static bool operator!= (BOX obj1, BOX obj2)
    {
        return !(obj1.length == obj2.length 
                    && obj1.breadth == obj2.breadth 
                    && obj1.height == obj2.height);
    }

    // this is third one 'Equals'
    public override bool Equals(BOX obj)
    {
        return (length == obj.length 
                    && breadth == obj.breadth 
                    && height == obj.height);
    }
}
_

_==_、_!=_、Equals演算子をオーバーライドするコードを適切に記述したと思います。ただし、次のようにコンパイルエラーが発生します。

_'myNameSpace.BOX.Equals(myNameSpace.BOX)' is marked as an override 
but no suitable method found to override.
_

だから、質問は-上記の演算子をオーバーライドしてこのエラーを取り除く方法は?

41

次のようにEqualsメソッドを宣言したと思います。

public override bool Equals(BOX obj)

object.Equalsメソッドはオブジェクトを受け取ります。このシグネチャでオーバーライドするメソッドはありません。次のようにオーバーライドする必要があります。

public override bool Equals(object obj)

タイプセーフEquals,実装できますIEquatable<BOX>

31
Selman Genç

Selman22が言ったように、デフォルトのobject.Equalsメソッド。object objおよび安全なコンパイル時タイプではありません。

それを実現するために、型に IEquatable<Box>

public class Box : IEquatable<Box>
{
    double height, length, breadth;

    public static bool operator ==(Box obj1, Box obj2)
    {
        if (ReferenceEquals(obj1, obj2))
        {
            return true;
        }

        if (ReferenceEquals(obj1, null))
        {
            return false;
        }
        if (ReferenceEquals(obj2, null))
        {
            return false;
        }

        return (obj1.length == obj2.length
                && obj1.breadth == obj2.breadth
                && obj1.height == obj2.height);
    }

    // this is second one '!='
    public static bool operator !=(Box obj1, Box obj2)
    {
        return !(obj1 == obj2);
    }

    public bool Equals(Box other)
    {
        if (ReferenceEquals(null, other))
        {
            return false;
        }
        if (ReferenceEquals(this, other))
        {
            return true;
        }

        return height.Equals(other.height) 
               && length.Equals(other.length) 
               && breadth.Equals(other.breadth);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        return obj.GetType() == GetType() && Equals((Box)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hashCode = height.GetHashCode();
            hashCode = (hashCode * 397) ^ length.GetHashCode();
            hashCode = (hashCode * 397) ^ breadth.GetHashCode();
            return hashCode;
        }
    }
}

もう1つ注意すべきことは、等価演算子を使用して浮動小数点比較を行っているため、精度が失われる可能性があることです。

47
Yuval Itzchakov

実際、これは「ハウツー」テーマです。したがって、参照実装は次のとおりです。

    public class BOX
    {
        double height, length, breadth;

        public static bool operator == (BOX b1, BOX b2)
        {
            if (null == b1)
                return (null == b2);

            return b1.Equals(b2);
        }

        public static bool operator != (BOX b1, BOX b2)
        {
            return !(b1 == b2);
        }

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
                return false;

            var b2 = (BOX)obj;
            return (length == b2.length && breadth == b2.breadth && height == b2.height);
        }

        public override int GetHashCode()
        {
            return height.GetHashCode() ^ length.GetHashCode() ^ breadth.GetHashCode();
        }
    }

参照: https://msdn.Microsoft.com/en-us/library/336aedhh(v = vs.100).aspx#Examples

19
epox