Constrained Generics and Return Values

I was working on some mocking stuff today and I ran into an odd situation. Let's say you have the following class hierarchy:

public abstract class Cup
{
}

public class CoffeeCup : Cup
{
}

public class Shotglass : Cup
{
}

Now, let's define a factory that randomly creates cups:

public static class CupCreator
{
    public static T Create<T>() where T : Cup
    {
        if(DateTime.Now.Second % 2 == 0)
        {
            return new Shotglass();
        }
        else
        {
            return new CoffeeCup();
        }
    }
}

The problem is, the two return statements are in error - here's what the error statement looks like:

Cannot implicitly convert type 'Shotglass' to 'T'

It's error CS0029.

Here's the funny thing. 10 years ago, I would've assumed that there's something wrong with the compiler. I'm older now and I know that I'm probably the idiot :).

When I first did this, I thought, OK, T must be at least a Cup...so returning a CoffeeCup or a Shotglass should be OK, right?

Well, no. What if I call it like this?

var shot = CupCreator.Create<Shotglass>();

Then returning a CoffeeCup is invalid.

Just because T is constrained to be a Cup and the two return types descend from Cup doesn't mean the code is valid. It took me a bit to figure this one out!

* Posted at 08.18.2008 03:25:43 PM (Last Update: 08.19.2008 10:05:01 AM) | 2 comments | Link | RSS *

Comments

# clever compiler, from chuck at 08.18.2008 05:38:00 PM

Took me a while to see it. That's a pretty clever compiler. The compiler has to have a lot more rules to cover today, than 15 years ago in the world of C.

# How about returning Cup?, from Jason Haley at 08.19.2008 10:04:57 AM

Does it work if you return type Cup instead of T?

Add a Comment

(*) = Required field
Name (*):

E-Mail (*):

Web Site:

Title (*):

Comments (*):

Enter the code you see (*)



Quote
"The ultimate measure of a man is not where he stands in moments of comfort and convenience, but where he stands at times of challenge and controversy." Dr. Martin Luther King Jr.
Twitter History
follow me on Twitter
Blog History