简体   繁体   中英

Generic Compare throws “At least one object must implement IComparable.”

My Fancy Field Updater throws.

    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;
    }

I use this Updater for 'Value Types', System 'Reference Types' and my own 'Reference Types'. My types do not implement IComparable and I don't intend to do so. In those cases it is usually acceptable to just compare the references.

The point is that I want to be able to us it for anything. Is there a different implementation that would allow me to do so or do I have to catch the exception and try to handle those cases differently?

It looks like you don't really want to compare the values in terms of "greater than or less than" - but for equality. So you should use 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;
}

The default equality comparer does what you want for classes - it compares references for identity if the type doesn't either implement IEquatable<T> or override object.Equals .

You're checking if two values are equal using Comparer which is used to compare two values (sorting , greater than, less than and equal). Instead, use:

bool areEqual = EqualityComparer<T>.Default.Equals(target, value);

IComparer interface supports ordering comparisons. That is, when the Compare method returns 0, it means that two objects sort the same. Implementation of exact equality comparisons is provided by the IEqualityComparer generic interface.

IComparable is an interface that lets YOU (the developer) determine if two objects, for purposes of your application, should be treated as "equal". You might be a little less resistant to using the interface, friend, as it facilitates the work that you have to do and doesn't require that you generate external methods to compare your objects. The try-catch approach will work, but it's crude and you'll end up cutting and pasting it all over your code.

Think MAINTAINABILITY.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM