如何覆盖!= 运算符?

我尝试覆盖 != 运算符:


public class Box

{

    public Box()

    {

    }


    public Box(double height, double width)

    {

        Height = height;

        Width = width;

    }


    public double Height { get; set; }

    public double Width { get; set; }


    public override int GetHashCode()

    {

        unchecked

        {

            return (Height.GetHashCode() * 397) ^ Width.GetHashCode();

        }

    }

    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);

    }


    protected bool Equals(Box other)

    {

        return Math.Abs(Height - other.Height) + Math.Abs(Width - other.Width) < 0.001;

    }

    public static bool operator ==(Box left, Box right)

    {

        if (ReferenceEquals(null, left))

            return false;


        if (ReferenceEquals(null, right))

            return false;


        return left.Equals(right);

    }


    public static bool operator !=(Box left, Box right)

    {

        var t = !(left == right);

        return t;

    }

}


public class BetterBox:Box{


}

并尝试使用 != 运算符


var box = new Box();

var betterBox = box as BetterBox;

if(betterBox!=null){

    --do-something

}

在这种情况下 != returntrue并且代码进入if. 这里有什么问题?为什么会发生?

在 mdsn 我看到相同的代码:https ://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/336aedhh%28v%3dvs.100%29


BIG阳
浏览 202回答 2
2回答

慕姐8265434

这是Box使用相等检查的完整实现(实现IEquatable<Box>)。以下是测试结果:&nbsp; &nbsp; &nbsp; &nbsp;a&nbsp; &nbsp; &nbsp; &nbsp; b&nbsp; &nbsp; &nbsp;a==b&nbsp; &nbsp; &nbsp;a!=b&nbsp; &nbsp; a.Equals(b)&nbsp; &nbsp; b.Equals(a)&nbsp; &nbsp; null&nbsp; &nbsp; &nbsp;null&nbsp; &nbsp; &nbsp;True&nbsp; &nbsp; False&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;[30×10]&nbsp; &nbsp; &nbsp;null&nbsp; &nbsp; False&nbsp; &nbsp; &nbsp;True&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; False&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[30×10]&nbsp; [30×10]&nbsp; &nbsp; &nbsp;True&nbsp; &nbsp; False&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;True&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;True&nbsp; &nbsp; null&nbsp; [30×10]&nbsp; &nbsp; False&nbsp; &nbsp; &nbsp;True&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;False我已经实现了Equals(Box), Equals(object), GetHashCode(), operator ==,operator !=和ToString().public class Box : IEquatable<Box>{&nbsp; &nbsp; // Place values in constants&nbsp; &nbsp; public const double SizeTolerance = 0.001;&nbsp; &nbsp; public double Width { get; set; }&nbsp; &nbsp; public double Height { get; set; }&nbsp; &nbsp; public static bool operator ==(Box left, Box right)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if(!ReferenceEquals(left, null))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // consider that left.Equals(null) should return false&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return left.Equals(right);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return ReferenceEquals(left, right);&nbsp; &nbsp; }&nbsp; &nbsp; public static bool operator !=(Box left, Box right)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return !(left==right);&nbsp; &nbsp; }&nbsp; &nbsp; #region IEquatable Members&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Equality overrides from <see cref="System.Object"/>&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="obj">The object to compare this with</param>&nbsp; &nbsp; /// <returns>False if object is a different type, otherwise it calls <code>Equals(Box)</code></returns>&nbsp; &nbsp; public override bool Equals(object obj)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if(obj is Box other)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Equals(other);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Checks for equality among <see cref="Box"/> classes&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="other">The other <see cref="Box"/> to compare it to</param>&nbsp; &nbsp; /// <returns>True if equal</returns>&nbsp; &nbsp; public bool Equals(Box other)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if(ReferenceEquals(other, null))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return Math.Abs(Width-other.Width)<SizeTolerance&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && Math.Abs(Height-other.Height)<SizeTolerance;&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Calculates the hash code for the <see cref="Box"/>&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <returns>The int hash value</returns>&nbsp; &nbsp; public override int GetHashCode()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; unchecked&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int hc = 17;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hc = 23*hc + Width.GetHashCode();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hc = 23*hc + Height.GetHashCode();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return hc;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; #endregion&nbsp; &nbsp; public override string ToString()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $"[{Width}×{Height}]";&nbsp; &nbsp; }}以及测试它的代码:&nbsp; &nbsp; static void Main(string[] args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Debug.WriteLine($"{"a",8} {"b",8} {"a==b",8} {"a!=b",8} {"a.Equals(b)",14} {"b.Equals(a)",14}");&nbsp; &nbsp; &nbsp; &nbsp; Box a = null;&nbsp; &nbsp; &nbsp; &nbsp; Box b = null;&nbsp; &nbsp; &nbsp; &nbsp; Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");&nbsp; &nbsp; &nbsp; &nbsp; a = new Box() { Height = 10, Width = 30 };&nbsp; &nbsp; &nbsp; &nbsp; Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");&nbsp; &nbsp; &nbsp; &nbsp; b = new Box() { Height = 10, Width = 30 };&nbsp; &nbsp; &nbsp; &nbsp; Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");&nbsp; &nbsp; &nbsp; &nbsp; a = null;&nbsp; &nbsp; &nbsp; &nbsp; Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");&nbsp; &nbsp; }}

千巷猫影

您对==运算符的实现是错误的。检查空值时需要考虑两个操作数。目前,如果left为 null,则返回 false,忽略right操作数的值。如果他们两个都是null它应该返回true。public static bool operator ==(Box left, Box right){&nbsp; &nbsp; var isLeftNull = ReferenceEquals(null, left);&nbsp; &nbsp; var isRightNull = ReferenceEquals(null, right);&nbsp; &nbsp; if (isLeftNull && isRightNull)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }&nbsp; &nbsp; if (isLeftNull || isRightNull)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }&nbsp; &nbsp; return left.Equals(right);}
打开App,查看更多内容
随时随地看视频慕课网APP