Should derived classes hide the Default and Create static members inherited from Comparer<T>?

Viewed 198

I am writing an IComparer<T> implementation by deriving from the Comparer<T> class, as recommended by MSDN. For example:

public class MyComparer : Comparer<MyClass>
{
    private readonly Helper _helper;

    public MyComparer(Helper helper)
    {
         if (helper == null)
             throw new ArgumentNullException(nameof(helper));

        _helper = helper;
    }

    public override int Compare(MyClass x, MyClass y)
    {
        // perform comparison using _helper
    }
}

However, under this approach, the MyComparer class inherits the Default and Create static members from the Comparer<T> class. This is undesirable, since the implementation of the said members is unrelated to my derived class, and may lead to misleading behaviour:

// calls MyClass.CompareTo or throws InvalidOperationException
MyComparer.Default.Compare(new MyClass(), new MyClass());

My comparer cannot have a default instance due to the required Helper argument, nor can it initialize itself from a Comparison<T>, so I cannot hide the inherited static members with meaningful implementations.

What is the recommended practice for such situations? I'm considering three options:

  • Implement IComparer<T> manually, rather than deriving from Comparer<T>, so as to avoid inheriting the said static members

  • Leave the inherited static members in place, and assume consumers will know not to use them

  • Hide the inherited static members with new implementations that throw InvalidOperationException:

    public static new Comparer<MyClass> Default
    {
        get { throw new InvalidOperationException(); }
    }
    
    public static new Comparer<MyClass> Create(Comparison<MyClass> comparison)
    {
        throw new InvalidOperationException();
    }
    
2 Answers
Related