请参阅以下代码:
public sealed class DateOfBirth : IEquatable<DateOfBirth>, IComparable<DateOfBirth>
{
private readonly DateTime _value;
public DateOfBirth(DateTime dateOfBirth)
{
if(dateOfBirth == DateTime.MinValue)
throw new ArgumentException("Invalid value.", "DateOfBirth");
this._value= dateOfBirth.date;
}
public DateTime Value
{
get { return _value; }
}
private static int Comparison(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
if (ReferenceEquals(dateOfBirth1, dateOfBirth2))
return 0;
else if (ReferenceEquals(dateOfBirth1, null))
return -1;
else if (ReferenceEquals(dateOfBirth2, null))
return 1;
if (dateOfBirth1._value < dateOfBirth2._value)
return -1;
else if (dateOfBirth1._value == dateOfBirth2._value)
return 0;
else if (dateOfBirth1._value > dateOfBirth2._value)
return 1;
return 0;
}
public int CompareTo(DateOfBirth other)
{
if (other != null)
return this._value.CompareTo(other._value);
else
throw new ArgumentNullException("DateOfBirth");
}
public static bool operator ==(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return Comparison(dateOfBirth1, dateOfBirth2) == 0;
}
public static bool operator !=(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return !(dateOfBirth1 == dateOfBirth2);
}
public static bool operator <(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return Comparison(dateOfBirth1, dateOfBirth2) < 0;
}
public static bool operator >(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return Comparison(dateOfBirth1, dateOfBirth2) > 0;
}
public static bool operator <=(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return Comparison(dateOfBirth1, dateOfBirth2) <= 0;
}
public static bool operator >=(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return Comparison(dateOfBirth1, dateOfBirth2) >= 0;
}
public bool Equals(DateOfBirth other)
{
if (ReferenceEquals(other, null))
return false;
return _value == other._value;
}
public override bool Equals(object obj)
{
return Equals(obj as DateOfBirth);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
}
我意识到它可以被认为是过度设计一个简单的出生日期。我更感兴趣的是九个比较(https://ericlippert.com/2013/10/07/math-from-scratch-part-six-comparisons/)是否正确实施。这篇文章帮助我:https://blogs.msdn.microsoft.com/abhinaba/2005/10/11/c-comparison-operator-overloading-and-spaceship-operator/ - 我对本文代码的唯一关注是比较方法没有这样做(我的代码所做的):
if (ReferenceEquals(dateOfBirth1, dateOfBirth2))
return 0;
else if (ReferenceEquals(dateOfBirth1, null))
答案 0 :(得分:0)
您不需要自己处理所有这些比较。相反,将比较工作委托给基础DateTime _value
。
MSDN包含有关how to override Equals
method and overload ==
operator的全面文档。我认为此文档中没有任何内容可以添加。同样,由于您依赖于支持比较的基础值,您的:
public static bool operator ==(DateOfBirth dateOfBirth1, DateOfBirth dateOfBirth2)
{
return Comparison(dateOfBirth1, dateOfBirth2) == 0;
}
可以简单地写成:
public static bool operator ==(DateOfBirth d1, DateOfBirth d2)
{
return d1._value == d2._value;
}
同样,DateTime
本身只是delegated the comparison to long
:
public struct DateTime : ...
{
...
public static bool operator ==(DateTime d1, DateTime d2)
{
return d1.InternalTicks == d2.InternalTicks;
}
}
请注意,由于DateTime
是struct
,因此您知道_value
字段中的值始终为。{1}}。如果您使用class
,情况会有所不同:在这种情况下,最简单的方法是在构造函数中禁止null
值;在比较方法中处理它们也是可能的,但是需要更多代码并且更容易出错。
顺便说一句,确保你有充分的理由让DateOfBirth
成为一个班级,而不是struct
,并将其标记为密封。