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

Question regarding declaration of equality operators in C#

这看起来非常基础,但我找不到关于这个特定笔记的任何其他答案。在 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);
    }

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