I'm trying to convert from some Java code, and I've got one massively complicated headache. Bear with me while I see if I can provide a comprehensible explanation.
Let's suppose I have an abstract class called BaseDatatype. Other classes will inherit from this, e.g. StringDatatype, NumericDatatype and so on.
Now, all datatypes should be comparable, but I'd like to have different methods for comparing same types.
So, I write this interface:
interface IDataComparable <X> where X : BaseDatatype
{
CompareResult compareAnyType( BaseDatatype instance );
CompareResult compareSameType( X instance );
}
So far, so good.
Now for the top level implementation, which will be abstract. In C#, abstract classes must declare interface methods, so we must have:
abstract class BaseDatatype : IDataComparable<BaseDatatype>
{
abstract CompareResult compareAnyType( BaseDatatype instance );
abstract CompareResult compareSameType( BaseDatatype instance );
}
But this misses the point. What I really want to enforce is having to write:
class StringDatatype : BaseDatatype
{
CompareResult compareAnyType( BaseDatatype instance ) { ... }
CompareResult compareSameType( StringDatatype instance ) { ... }
}
(note the use of StringDatatype) but I can't see how that would happen.
I could forgo this particular behaviour, but this is only part of the problem - there are a lot more reasons for wanting this related to gaining any benefit from generics.
As for how I did it in Java, it's fairly complex, if not plain horrible.
public abstract class BaseDatatype< X extends BaseDatatype < ? > > implements DataComparable<X>
{
//not forced to implement methods
}
public interface DataComparable<X extends BaseDatatype< ? >>
{
CompareResult compareAnyType( BaseDatatype< ? > instance );
CompareResult compareSameType( X instance );
}
public class StringData extends BaseDatatype<StringData>
{
CompareResult compareAnyType( BaseDatatype< ? > instance ) { ... }
CompareResult compareSameType( StringData instance ) { ... }
}
i.e. recursive generics (which C# has) and unbounded wilcards (which it doesn't). Charming eh!
Does this make the slightest bit of sense? Any clues?
Thanks!