Welcome to MSDN Blogs Sign in | Join | Help

Generics and Wildcards

Martin write a post entitled Generics: The Importance of Wildcards

He concludes with:

Unfortunately, C# will not support wildcards or a similar mechanism. The implementation strategy does not allow the introduction of wildcards (generics are implemented in the runtime instead of by type erasure). This is a bit surprising, since the implementation strategy is often claimed to be superior. What disappoints me is that the designers of C# are not willing to admit that subtyping is an issue and that wildcards are a solution.

That's a very binary statement, when in fact the implementation of generics both in the .NET and Java worlds are exercises in tradeoffs.

I agree that subtyping is an issue, and that wildcards are *a* solution (I don't know enough to know whether it is the only solution, or whether a solution that worked only on reference types would be interesting.). But, having looked at the implementation of wildcards in Java, they add a fair amount of complexity to the language, and I'm not sure that the added flexibility that they give you is important enough to add language complexity. I do know that when I was talking to C# users, the ability to do this was not one of the things that came up.

When I weigh the speculative benefits there against the known benefits of the .NET implementation - collections of primitive types, for example - it's pretty clear which one I would prefer.

Published Thursday, May 26, 2005 2:08 PM by ericgu
Filed under:

Comments

Thursday, May 26, 2005 4:38 PM by Scott Wisniewski

# re: Generics and Wildcards

Wildcard types are a good idea, however their implementation in Java is seriously broken.

In particular, a wildcard can only be successfully used if it appears at the root of a parameterized type tree. Consider something like this :

public class Pair<T1, T2>
{
public T1 First;
public T2 Second;
}

and this:

public class HashSomeMethods
{
public static void Foo(LinkedList<Pair<?, ?>> list)
{
//... code here
}

public static void Main(String[] args)
{
Foo(new LinkedList<Pair<Integer, String>>());
}
}

In examining this code it looks like it should work. However, it doesn't. Compiling this code with either sun's javac or the compiler built into eclipse will generate an error at the call site of Foo, stating that LinkedList<Pair<Integer, String>> cannot be converted to LinkedList<Pair<?, ?>>.

However, if Foo was redefined as follows:

public static void Foo(LinkedList<?>)
{
//... code here
}

then it would work.

The presence of WildCard types introduces polymorphisim that has the same problems as polymorphic arrays: they violate type safety.

Saying that

A <: B ==> C<A> <: C<B>

is, in general, not sound.

lets say we had something like this:

class C<T>
{
void method(T param)
{
//....
}
}

class C2 extends C<B>
{
void method(B param)
{
//do some B specific stuff to param
}
}

and code like this:

C<? extends A> x = new C2<B>();
x.method(new A());

This code will most certanlty fail at run time because C2<B>.method is expecting an B, but its actually getting an A.

However, keeping a method expecting a B from getting an A is exactly the type of thing that a type system is soposed to prevent.
Thursday, May 26, 2005 4:54 PM by Scott Wisniewski

# re: Generics and Wildcards

Please Ignore my second point (the one about subtyping).

Java Wild Card Types require an explicit lower bound to be set before parameters can be passed...


However, my first point (about wildcard matching being broken) is still valid
Friday, May 27, 2005 8:44 AM by Iulian

# re: Generics and Wildcards

It works if you change the declaration of Foo as follows:

public static void Foo(LinkedList<? extends Pair<?, ?>> list) {
System.out.println(list.get(0).First);
}

The explanation is that a type like C<?> is a supertype of any instantiation of the generic class C. However, C<A> and C<B> are unrelated types no matter what is the relation between A and B. So, even though Pair<?, ?> is a supertype of Pair<Integer, String>, LinkedList<Pair<...>> is not a supertype of any other instantiation of LinkedList. But a LinkedList<? ... > can be, so you just add the wildcard with the bound you want.

Iulian
Friday, May 27, 2005 10:04 AM by C. Scott Ananian

# re: Generics and Wildcards

The Java implementation isn't "seriously broken" by a long shot -- but it *is* seriously *hairy*. I played around with each beta as this was being developed, and believe me, there are a lot of dark corners. Some interesting possibilities (ie, wildcards and proper array variance) didn't end up making the Java 1.5 release because they were just a little *too* hairy to be confident in, given the release time frame.

I think there is likely some improvement in error messages to be done (the compiler should have suggested the variant type the second poster provided, given the erroneous code of the first poster, etc), but the theory is certainly solid.

# Eric Gunnerson s C Compendium Generics and Wildcards | Green Tea Fat Burner

# Eric Gunnerson s C Compendium Generics and Wildcards | Quick Diets

New Comments to this post are disabled
 
Page view tracker