有关在C#中声明相等运算符的问题

时间:2018-12-30 19:47:56

标签: c# operators

这似乎非常基础,但是我在此特殊注释上找不到其他答案。在C#中声明==运算符时,还必须声明!=运算符。显然,每种情况都可能因类型而异,但是如果类型具有显式相等性或不具有显式相等性,则将!=声明为简单的!(a == b)是否合理?有没有理由不这样做吗?例如:

    public static bool operator ==(Point p1, Point p2)
    {
        return ((p1.X == p2.x) && (p1.Y == p2.Y));
    }

    public static bool operator !=(Point p1, Point p2)
    {
        return !(p1 == p2);
    }

1 个答案:

答案 0 :(得分:2)

Microsoft Docs有一个很好的例子:How to: Define Value Equality for a Type涵盖了定义类型相等的重要方面。

在下面的示例中,对于x!=y,您会看到它只是返回!(x==y)

using System;
class TwoDPoint : IEquatable<TwoDPoint>
{
    // Readonly auto-implemented properties.
    public int X { get; private set; }
    public int Y { get; private set; }

    // Set the properties in the constructor.
    public TwoDPoint(int x, int y)
    {
        if ((x < 1) || (x > 2000) || (y < 1) || (y > 2000))
        {
            throw new System.ArgumentException("Point must be in range 1 - 2000");
        }
        this.X = x;
        this.Y = y;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as TwoDPoint);
    }

    public bool Equals(TwoDPoint p)
    {
        // If parameter is null, return false.
        if (Object.ReferenceEquals(p, null))
        {
            return false;
        }

        // Optimization for a common success case.
        if (Object.ReferenceEquals(this, p))
        {
            return true;
        }

        // If run-time types are not exactly the same, return false.
        if (this.GetType() != p.GetType())
        {
            return false;
        }

        // Return true if the fields match.
        // Note that the base class is not invoked because it is
        // System.Object, which defines Equals as reference equality.
        return (X == p.X) && (Y == p.Y);
    }

    public override int GetHashCode()
    {
        return X * 0x00010000 + Y;
    }

    public static bool operator ==(TwoDPoint lhs, TwoDPoint rhs)
    {
        // Check for null on left side.
        if (Object.ReferenceEquals(lhs, null))
        {
            if (Object.ReferenceEquals(rhs, null))
            {
                // null == null = true.
                return true;
            }

            // Only the left side is null.
            return false;
        }
        // Equals handles case of null on right side.
        return lhs.Equals(rhs);
    }

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