链接以清理CompareTo
本文关键字:CompareTo 链接 | 更新日期: 2023-09-27 18:30:12
每次我需要在C#中编写CompareTo
方法时,我都讨厌这样一个事实,即我不能像在JavaScript:中那样将测试和结果链接起来
function int compareTo(a, b) {
return a.Value1 - b.Value1 || a.Value2 - b.Value2 || a.Value3 - b.Value3;
}
相反,在C#中,这看起来像:
int CompareTo(object obj)
{
var other = obj as MyClass;
if (other == null)
return 0;
int result = Value1 - other.Value1;
if (result != 0)
return result;
result = Value2 - other.Value2;
if (result != 0)
return result;
return Value3 - other.Value3;
}
有没有办法写出上面的"清洁剂"?它不必像JavaScript中那样是一行代码,但应该更可读,不易出错。
使用通用扩展方法NullableCompareTo
,我们现在可以使用?? operator
将CompareTo
方法重构为:
int CompareTo(object obj)
{
var other = obj as MyClass;
if (other == null)
return 0;
return Value1.NullableCompareTo(other.Value1)
?? Value2.NullableCompareTo(other.Value2)
?? Value3.CompareTo(other.Value3);
}
扩展方法
public static class ComparableExtensions
{
/// <summary>
/// Same as CompareTo but returns null instead of 0 if both items are equal.
/// </summary>
/// <typeparam name="T">IComparable type.</typeparam>
/// <param name="this">This instance.</param>
/// <param name="other">The other instance.</param>
/// <returns>Lexical relation between this and the other instance or null if both are equal.</returns>
public static int? NullableCompareTo<T>(this T @this, T other) where T : IComparable
{
var result = @this.CompareTo(other);
return result != 0 ? result : (int?)null;
}
}
您可以使用扩展方法来模拟??
。
public static class Extensions {
public static T Coalesce<T>( this T self, T valueIfDefault ) {
return self.Equals( default(T) ) ? valueIfDefault : self;
}
}
例如,0.Coalesce(1).Coalesce(2)
、0.Coalesce(0).Coalesce(1)
和1.Coalesce(2).Coalesce(3)
将分别为1。
你可以使用一个较短的名字,这取决于你个人对清晰与简洁的偏好。
以下是以这种风格改写的问题的比较方法:
int CompareTo(object obj) {
var other = obj as MyClass;
if( other == null )
return 0;
return (Value1 - other.Value1).Coalesce(Value2 - other.Value2)
.Coalesce(Value3 - other.Value3);
}
如果个别比较比较比较昂贵,您还可以添加:
public static T Coalesce<T>( this T self, Func<T> valueIfDefault ) {
return self.Equals( default(T) ) ? valueIfDefault() : self;
}
这将被称为类似(Value1 - other.Value1).Coalesce(() => CompareExpensively(Value2, other.Value2)).Coalesce(Value3 - other.Value3)
。