Search code examples
c#genericsicomparable

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?


Solution

  • 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.