C# “通用比较抛出”;至少有一个对象必须实现IComparable。”;

C# “通用比较抛出”;至少有一个对象必须实现IComparable。”;,c#,generics,icomparable,C#,Generics,Icomparable,我喜欢的字段更新程序抛出 public static bool UpdateField<T>(ref T target, T value) { bool updated; if (0 != Comparer<T>.Default.Compare(target, value)) { target = value; updated = true; }

我喜欢的字段更新程序抛出

    public static bool UpdateField<T>(ref T target, T value)
    {
        bool updated;
        if (0 != Comparer<T>.Default.Compare(target, value))
        {
            target = value;
            updated = true;
        }
        else
        {
            updated = false;
        }
        return updated;
    }
公共静态布尔更新字段(参考T目标,T值)
{
布尔更新;
如果(0!=Comparer.Default.Compare(目标,值))
{
目标=价值;
更新=真;
}
其他的
{
更新=错误;
}
更新的回报;
}
我将此更新程序用于“值类型”、系统“引用类型”和我自己的“引用类型”。我的类型没有实现IComparable,我也不打算这样做。在这些情况下,仅比较参考文献通常是可以接受的


关键是我想为任何事都能做到这一点。是否有一个不同的实现允许我这样做,或者我必须捕获异常并尝试以不同的方式处理这些情况?

看起来您并不是真的想比较“大于或小于”的值,而是为了相等。因此,您应该使用
EqualityComparer.Default

public static bool UpdateField<T>(ref T target, T value)
{
    bool updated = !EqualityComparer<T>.Default.Equals(target, value);
    if (updated)
    {
        target = value;
    }
    return updated;
}
公共静态布尔更新字段(参考T目标,T值)
{
bool updated=!EqualityComparer.Default.Equals(目标,值);
如果(更新)
{
目标=价值;
}
更新的回报;
}

默认相等比较器对类执行您想要的操作-如果类型未实现
IEquatable
或重写
对象,则它会比较标识引用。Equals

您正在使用用于比较两个值(排序、大于、小于和等于)的比较器检查两个值是否相等。相反,请使用:

bool areEqual = EqualityComparer<T>.Default.Equals(target, value);
bool areEqual=EqualityComparer.Default.Equals(目标,值);
IComparer接口支持排序比较。也就是说,当 Compare方法返回0,这意味着两个对象排序相同。 IEqualityComparer通用接口。


IComparable是一个接口,它允许您(开发人员)确定应用程序中的两个对象是否应被视为“相等”。friend,您可能对使用接口不那么抗拒,因为它简化了您必须完成的工作,并且不需要生成外部方法来比较对象。try-catch方法会起作用,但它很粗糙,最终会将其剪切并粘贴到代码中


考虑可维护性。

是什么使得给定的引用大于或小于另一个引用?顺便说一句,将常量放在比较运算符的LHS上对于C#来说是非常规的。似乎您想要检查相等(等于或不等于),而不是比较(大于、小于、等于)。那么,为什么不直接使用
target.Equals(value)
,并依赖于被覆盖的值来进行值比较呢。@Servy对于引用,如果不相等,我只会更新。我不是按照默认值这样做的,因为对于值类型,我希望比较值而不是它们的引用。@juharr是的,比较相等是我的用例。如果在别处决定更新,我会使用这些信息。如果target为null,则将抛出target.Equals(value)。Object.Equals会实现我想要的吗?值类型会实现该接口,它不仅仅用于检查相等性,因为它还会告诉您一个对象大于或小于另一个对象。
IComparable显然不适用于值类型。
这只是错误。有许多可比较的值类型<代码>它是一个界面,可用于确定两个对象[…]是否应被视为“相等”。否。同样,它可用于确定给定对象是否大于、小于或等于另一个对象
IEquatable
用于确定一个对象是否等于另一个对象。我非常高兴收回我关于此接口和值类型的声明。但我认为我的选民们没有抓住重点。从长远来看,Try-catch是不可维护的。您的第一句话仍然是错误的:“IComparable是一个接口,它允许您(开发人员)确定两个对象在应用程序中是否应被视为“相等”。“它不是用于确定顺序。在极少数情况下,对象可能是相等的,但仍然以这样或那样的方式排列。@codenoir:它肯定找不到“它们的相似之处或不同之处”。您的定义完全错误-您定义的是
IEquatable
,而不是
IComparable
。MSDN是一个比字典更好的参考资料…我很好奇,有没有理由更喜欢这个而不是
!target.Equals(value)
?@juharr:Yes:如果类型实现了
IEquatable
,则默认的相等比较器将直接调用它。特别是,当您使用值类型时,这避免了装箱。@juharr另外,如果
target
null