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>
开发者_如何学JAVA{
// 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?
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.
Short answer: it depends.
In your specific example, I would say it is almost always the wrong thing to do to create an unnecessary interface (IMyClass
in this case) because it just creates work for you. Rule of thumb: use interfaces only when more than one class implements them. And as you point out this particular interface doesn't even accomplish the goal of making your class directly comparable.
As far as which classes should implement IComparable
, generic or otherwise, it depends entirely on what your comparison needs are. If comparison is always done between references to the base class, the derived class doesn't need to implement the interface as it will never be called.
精彩评论