Constraints in Generic classes: C# vs. Java
The extra syntax in Java just don't seem that useful to me.There’s been an interesting discussion on the Visual C# language forums relating to generic class constraints. For background, C# lets you specify two forms of constraints in a generic class. First, you can specify that the generic type must be derived from a particular base class:
public class MyType<T> where T : MyBaseClass
means that any class you substitute for T must be derived from MyBaseClass.
Secondly, you can specify that T must implement some interface:
public class MyType<T> where T : IComparable
As a special case, you can also specify a generic interface:
public class MyType<T> where T : IComparable<T>
What you can’t do in C# (but you can in Java) is specify that the type substituted for a generic parameter is a base class of some type
// In Java 5:
void setComparer( Comparator<? super E> c ) { … }
I may be in the minority here, but I just don’t see compelling needs for that additional language functionality. I’m not going to post the original example, but if you go here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=104825&SiteID=1 you can see the entire thread.
The book example from the above link is interesting, but I can easily provide two possible modifications within the C# language that work just as well, or even better.
The first plan is to modify the NamedObjectComparer class so that it’s a generic class, and simply use that:
public class NamedObjectComparer<T> : IComparer<T>
where T : INamedObject
{ … }
Then, you create the sorted collection using this class:
new SortedCollection<Book>(new NamedObjectComparer<Book>());
In my opinion, this has a couple advantages over the version posted. First, I’m concerned about the non-generic NamedObjectComparer:
public class NamedObjectComparer: IComparer<INamedObject>
{
public int Compare(INamedObject a, INamedObject b)
{
return String.Compare(a.Name, b.Name);
}
}
I’m not sure this has real meaning (or at least that it’s really what the author intended). The NamedObjectComparer can be used to compare any two objects that have names. Do you really want to compare a Book to an Employee? Or a Street to a Customer? That’s valid with this object, but I doubt that have a proper semantic meaning.
Of course, if you really did intend to compare different types that both have names, simply change the declaration of the collection:
new SortedCollection<INamedObject>(new NamedObjectComparer());
But, based on the examples in the forum, I can’t find a reasonable use case for constraining a type to be a superclass of a type rather than a subtype. If you have a good example, I’m interested in seeing it. Please comment or respond in the original forum.