在C#中为依赖于运算符本身的复杂类型编写运算符重载

在C#中为依赖于运算符本身的复杂类型编写运算符重载,c#,null,operator-overloading,stack-overflow,C#,Null,Operator Overloading,Stack Overflow,我有一个称为“半天”的复杂类型,它是DateTime和枚举值的组合,表示AM/PM public class HalfDay { private DateTime _Date; public DateTime Date { get { return _Date; } set { _Date = value.Date; } } private DayHalf _Half; public DayHalf Half { get { return _Half; } set { _Half

我有一个称为“半天”的复杂类型,它是DateTime和枚举值的组合,表示AM/PM

public class HalfDay
{
  private DateTime _Date;
  public DateTime Date { get { return _Date; } set { _Date = value.Date; } }
  private DayHalf _Half;
  public DayHalf Half { get { return _Half; } set { _Half = value; } }
}
我试图编写一组重载运算符来比较两个半天

    public static bool operator <(HalfDay halfday1, HalfDay halfday2)
    {
        if (halfday1.Date.Date < halfday2.Date.Date) return true;
        if (halfday1.Date == halfday2.Date && halfday1.Half < halfday2.Half) return true;
        return false;
    }

    public static bool operator >(HalfDay halfday1, HalfDay halfday2)
    {
        if (halfday1.Date.Date > halfday2.Date.Date) return true;
        if (halfday1.Date == halfday2.Date && halfday1.Half > halfday2.Half) return true;
        return false;
    }

    public static bool operator ==(HalfDay halfday1, HalfDay halfday2)
    {
        if (halfday1 == null && halfday2 == null) return true;
        if (halfday1 == null || halfday2 == null) return false;

        return halfday1.Date.Date == halfday2.Date.Date && halfday1.Half == halfday2.Half;
    }

    public static bool operator !=(HalfDay halfday1, HalfDay halfday2)
    {
        if (halfday1 == null && halfday2 == null) return false;
        if (halfday1 == null || halfday2 == null) return true;

        return !(halfday1 == halfday2);
    }
公共静态布尔运算符(半天半天1,半天半天2)
{
如果(halfday1.Date.Date>halfday2.Date.Date)返回true;
if(halfday1.Date==halfday2.Date&&halfday1.Half>halfday2.Half)返回true;
返回false;
}
公共静态布尔运算符==(半天半天1,半天半天2)
{
if(halfday1==null&&halfday2==null)返回true;
if(halfday1==null | | halfday2==null)返回false;
返回halfday1.Date.Date==halfday2.Date.Date&&halfday1.Half==halfday2.Half;
}
公共静态布尔运算符=(半天半天1,半天半天2)
{
if(halfday1==null&&halfday2==null)返回false;
if(halfday1==null | | halfday2==null)返回true;
返回!(半天1==半天2);
}
在真正的新手风格中(我以前从未编写过运算符),我使用==比较将半天与null进行比较。当然,当递归调用我的运算符代码时,结果是堆栈溢出

我认为我需要检查运算符中的null,以便正确返回false(或true),以便在任何参数为null的情况下进行比较。不过,我显然误解了OOP的一些基本原理——有没有关于如何正确编写这些运算符的建议?

请尝试使用:

尝试改用:

尝试改用:

尝试改用:

见:

运算符==重载中的一个常见错误是使用(A==b),(A== null),或(b==null)来检查引用是否相等。而是这个 结果调用重载运算符==,导致无限大的 环使用ReferenceEquals或将类型强制转换为对象,以避免 循环

要将其与
null
进行比较,可以执行以下操作(文档中的示例代码):

另见:

默认情况下,操作符==通过确定两个引用是否指示相同的对象来测试引用相等性,因此引用类型不需要实现操作符==来获得此功能。当类型是不可变的,这意味着实例中包含的数据无法更改时,重载运算符==以比较值相等而不是引用相等可能会很有用,因为作为不可变对象,只要它们具有相同的值,就可以认为它们是相同的不建议在非不可变类型中使用重写运算符==。

请参阅:

运算符==重载中的一个常见错误是使用(A==b),(A== null),或(b==null)来检查引用是否相等。而是这个 结果调用重载运算符==,导致无限大的 环使用ReferenceEquals或将类型强制转换为对象,以避免 循环

要将其与
null
进行比较,可以执行以下操作(文档中的示例代码):

另见:

默认情况下,操作符==通过确定两个引用是否指示相同的对象来测试引用相等性,因此引用类型不需要实现操作符==来获得此功能。当类型是不可变的,这意味着实例中包含的数据无法更改时,重载运算符==以比较值相等而不是引用相等可能会很有用,因为作为不可变对象,只要它们具有相同的值,就可以认为它们是相同的不建议在非不可变类型中使用重写运算符==。

请参阅:

运算符==重载中的一个常见错误是使用(A==b),(A== null),或(b==null)来检查引用是否相等。而是这个 结果调用重载运算符==,导致无限大的 环使用ReferenceEquals或将类型强制转换为对象,以避免 循环

要将其与
null
进行比较,可以执行以下操作(文档中的示例代码):

另见:

默认情况下,操作符==通过确定两个引用是否指示相同的对象来测试引用相等性,因此引用类型不需要实现操作符==来获得此功能。当类型是不可变的,这意味着实例中包含的数据无法更改时,重载运算符==以比较值相等而不是引用相等可能会很有用,因为作为不可变对象,只要它们具有相同的值,就可以认为它们是相同的不建议在非不可变类型中使用重写运算符==。

请参阅:

运算符==重载中的一个常见错误是使用(A==b),(A== null),或(b==null)来检查引用是否相等。而是这个 结果调用重载运算符==,导致无限大的 环使用ReferenceEquals或将类型强制转换为对象,以避免 循环

要将其与
null
进行比较,可以执行以下操作(文档中的示例代码):

另见:


默认情况下,操作符==通过确定两个引用是否指示相同的对象来测试引用相等性,因此引用类型不需要实现操作符==来获得此功能。当类型是不可变的,这意味着实例中包含的数据无法更改时,重载运算符==以比较值相等而不是引用相等可能会很有用,因为作为不可变对象,只要它们具有相同的值,就可以认为它们是相同的不建议在非不可变类型中重写运算符==。

正如其他人已经提到的,当您想要检查引用相等性时,绕过任何
==
等于()
,使用

另外,当重载
==
时,您还应该重写
Equals()
(并实现public static bool operator ==(HalfDay halfday1, HalfDay halfday2) { if (Object.ReferenceEquals(halfday1, halfday2)) return true; if (Object.ReferenceEquals(halfday1, null) || Object.ReferenceEquals(halfday2, null)) return false; return halfday1.Date.Date == halfday2.Date.Date && halfday1.Half == halfday2.Half; }
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
    return false;
}
public bool Equals(HalfDay other)
{
    if (object.ReferenceEquals(other, null))
        return false;
    if (object.ReferenceEquals(other, this))
        return true;

   return this.Date.Date == other.Date.Date && this.Half == other.Half;
}

public int GetHashCode()
{
    // TODO
}

public override bool Equals(object other)
{
    return Equals(other as HalfDay);
}

public static bool operator ==(HalfDay halfday1, HalfDay halfday2)
{
    return object.Equals(halfday1, halfday2);
}

public static bool operator !=(HalfDay halfday1, HalfDay halfday2)
{
    return !(halfday1 == halfday2);
}