为了账号安全,请及时绑定邮箱和手机立即绑定

如何覆盖!= 运算符?

如何覆盖!= 运算符?

C#
BIG阳 2022-01-16 15:07:36
我尝试覆盖 != 运算符: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
查看完整描述

2 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

这是Box使用相等检查的完整实现(实现IEquatable<Box>)。以下是测试结果:


       a        b     a==b     a!=b    a.Equals(b)    b.Equals(a)

    null     null     True    False                              

 [30×10]     null    False     True          False               

 [30×10]  [30×10]     True    False           True           True

    null  [30×10]    False     True                         False

我已经实现了Equals(Box), Equals(object), GetHashCode(), operator ==,operator !=和ToString().


public class Box : IEquatable<Box>

{

    // Place values in constants

    public const double SizeTolerance = 0.001;


    public double Width { get; set; }

    public double Height { get; set; }


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

    {

        if(!ReferenceEquals(left, null))

        {

            // consider that left.Equals(null) should return false

            return left.Equals(right);

        }

        return ReferenceEquals(left, right);

    }

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

    {

        return !(left==right);

    }


    #region IEquatable Members

    /// <summary>

    /// Equality overrides from <see cref="System.Object"/>

    /// </summary>

    /// <param name="obj">The object to compare this with</param>

    /// <returns>False if object is a different type, otherwise it calls <code>Equals(Box)</code></returns>

    public override bool Equals(object obj)

    {

        if(obj is Box other)

        {

            return Equals(other);

        }

        return false;

    }


    /// <summary>

    /// Checks for equality among <see cref="Box"/> classes

    /// </summary>

    /// <param name="other">The other <see cref="Box"/> to compare it to</param>

    /// <returns>True if equal</returns>

    public bool Equals(Box other)

    {

        if(ReferenceEquals(other, null))

        {

            return false;

        }

        return Math.Abs(Width-other.Width)<SizeTolerance

            && Math.Abs(Height-other.Height)<SizeTolerance;

    }


    /// <summary>

    /// Calculates the hash code for the <see cref="Box"/>

    /// </summary>

    /// <returns>The int hash value</returns>

    public override int GetHashCode()

    {

        unchecked

        {

            int hc = 17;

            hc = 23*hc + Width.GetHashCode();

            hc = 23*hc + Height.GetHashCode();

            return hc;

        }

    }


    #endregion


    public override string ToString()

    {

        return $"[{Width}×{Height}]";

    }

}

以及测试它的代码:


    static void Main(string[] args)

    {

        Debug.WriteLine($"{"a",8} {"b",8} {"a==b",8} {"a!=b",8} {"a.Equals(b)",14} {"b.Equals(a)",14}");

        Box a = null;

        Box b = null;

        Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");

        a = new Box() { Height = 10, Width = 30 };

        Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");

        b = new Box() { Height = 10, Width = 30 };

        Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");

        a = null;

        Debug.WriteLine($"{a?.ToString()??"null",8} {b?.ToString()??"null",8} {a==b,8} {a!=b,8} {a?.Equals(b),14} {b?.Equals(a),14}");

    }

}


查看完整回答
反对 回复 2022-01-16
?
千巷猫影

TA贡献1829条经验 获得超7个赞

您对==运算符的实现是错误的。检查空值时需要考虑两个操作数。目前,如果left为 null,则返回 false,忽略right操作数的值。如果他们两个都是null它应该返回true。


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

{

    var isLeftNull = ReferenceEquals(null, left);

    var isRightNull = ReferenceEquals(null, right);


    if (isLeftNull && isRightNull)

    {

        return true;

    }


    if (isLeftNull || isRightNull)

    {

        return false;

    }


    return left.Equals(right);

}


查看完整回答
反对 回复 2022-01-16
  • 2 回答
  • 0 关注
  • 134 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信