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!