Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 链接以清理比较_C# - Fatal编程技术网

C# 链接以清理比较

C# 链接以清理比较,c#,C#,每次我需要在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;

每次我需要在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
我们现在可以利用重构
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;
    }
}
公共静态类CompariableExtensions
{
/// 
///与CompareTo相同,但如果两项相等,则返回null而不是0。
/// 
///i可比较类型。
///这个例子。
///另一个例子。
///此实例与其他实例之间的词法关系,如果两者相等,则为null。
公共静态int?NullableCompareTo(this T@this,T other),其中T:IComparable
{
var result=@this.CompareTo(其他);
返回结果!=0?结果:(int?)null;
}
}

您可以使用扩展方法来模拟
??

public static class Extensions {
    public static T Coalesce<T>( this T self, T valueIfDefault ) {
        return self.Equals( default(T) ) ? valueIfDefault : self;
    }
}
如果单个比较比较比较昂贵,您还可以添加:

public static T Coalesce<T>( this T self, Func<T> valueIfDefault ) {
    return self.Equals( default(T) ) ? valueIfDefault() : self;
}
public static T Coalesce(此T self,Func valueIfDefault){
返回self.Equals(默认值(T))?valueIfDefault():self;
}

这将被称为像
(Value1-other.Value1).合并(()=>比较昂贵(Value2,other.Value2)).合并(Value3-other.Value3)

我个人讨厌像
这样的名字,而且它实际上不是一行。而且,原来的版本更干净(发生的事情更明显)。这个解决方案更快还是更好?@Sinatr它在我的代码中被称为
test
,但为了答案的可读性,它改为
。如果你能想出一个更干净的版本,请share@Xaruth不,那叫分享。顺便说一句,我希望我的答案不是最好的答案,有人会想出一个更语言集成的解决方案。这就是重点。你问题中的代码就是我的答案。已经很好了。我希望能分享一些好的东西。使用lambda和
运算符来替换多个
if
和null检查(如果它们没有好处)并不是很好。我没看见他们。它应该更慢,更不明显。那么,是什么让这个解决方案更好呢?我问题中的代码显然可读性较差,更容易出错。它只显示了3种情况,但有时你有10多种情况下,事情很容易出错。这个解决方案的问题是,你要事先评估每个值。这就是为什么我使用lambda函数,下一个值只在前面等于0的情况下被评估,它们是<代码> int /代码>减法,所以我不认为这是一个显著的缺点。你的答案有额外的分支;在我的测试代码中有6对2,即2n对n-1,在后空测试代码中。如果没有基准测试,这些额外的分支机构似乎至少也会对性能产生负面影响。无论如何,问题中冗长的方法可能比两者都快。还有,你对我的答案投了反对票吗?我扩展了我的答案以涵盖这种情况。它们是
int
减法,因为我简化了这个问题,在我的代码中,它们是一些
string.Compare()
调用,因此改变了情况。
public static T Coalesce<T>( this T self, Func<T> valueIfDefault ) {
    return self.Equals( default(T) ) ? valueIfDefault() : self;
}