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 fromComparer<T>
, so as to avoid inheriting the said static membersLeave 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(); }