Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing an interface whereby generics are based on the interface

I am currently refactoring my code so that all important classes implement an interface (for unit testability). I came across a class that implements IComparable (non-templated); something like:

public MyClass : IComparable
{
    public int CompareTo(object obj)
    {
        MyClass cObj = obj as MyClass;
        if (cObj == null) { throw new ArgumentException(); }
        // etc.
    }
}

I'm wanting to interface it out, and use generics while I'm at it; something like this:

public IMyClass : IComparable<IMyClass>
{
    // Other methods here
}

public MyClass : IMyClass
{
    public CompareTo<IMyClass>(IMyClass other)
    {
        ...
    }
    // Other methods here
}

But then, ideally, MyClass should implement IComparable<MyClass> (and then subclasses of MyClass should implement IComparable<MySubClass>).

All of this to ask several questions:

What do you think of the approach I described? Is there a better way of doing this refactoring? Is there a point in making MyClass also implement IComparable<MyClass>, or is that pointless since we already implement IComparable<IMyClass>? Any pro-tips or "best"-practices I could be made aware of?

like image 394
Smashery Avatar asked Nov 04 '22 22:11

Smashery


1 Answers

Does it really make sense to have several objects of different types that are all comparable to each other? The language allows this, but I can count on 0 hands the number of times I've had to use it.

I'd recommend using IClass without being IComparable, and just have the derived classes implement IComparable.

P.S. I'm also against adding interfaces "for unit testability". If your program design calls for a factory pattern with interface-only coupling, then by all means code up that level of complexity. But don't abuse the design just to make your tests easier; use Moles instead.

like image 153
Stephen Cleary Avatar answered Nov 09 '22 11:11

Stephen Cleary