每次我需要在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那样是单行,但应该更具可读性且不易出错。
答案 0 :(得分:2)
使用通用扩展方法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;
}
}
答案 1 :(得分:1)
您可以使用扩展方法来模仿??
。
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)
。