Generic Parameter Inference

public static void Do<T>(this TBase value) where T : BaseClass<TBase>

The above line of code does not compile. I’ve been mulling over this for about half an hour and have not come up with a single logical reason why it shouldn’t, strong-typing wise, except that it doesn’t.

I can understand why using Type Inference (calling the method without the generic parameter), you could never bind to one predetermined T – after all, there may be an infinite amount of types that derive from BaseClass<TBase> and that’s just when using TBase‘s topmost level of inheritance.

However, using a call to Do with the T generic parameter explicitly stated, there can be only one option for TBase, since:

  1. It is a class and you can never derive twice from the same type in your line of inheritance, so there’s no fearing that T would derive from both BaseClass<A> and BaseClass<B> somewhere along that line.
  2. It is not an interface, where you could implement both ISomething<A> and ISomething<B>

Does anyone have any ideas?


8 thoughts on “Generic Parameter Inference

  1. Well, clearly the problem is that the hypothetical type parameter TBase is not in the list of bound type parameters (between the ). This would work (I think):
    public static void Do(this TBase value) where T : BaseClass
    But then of course C# would not be clever enough to infer T or TBase for you. This is just one of the limitations in C#s generics support which has bitten me in the past: many type safe programs are excluded :(
    In some ways Java generics, despite their reputation, are actually more powerful (e.g. consider that you can keep around an ArrayList<Whatever>), but even Javas use site variance won’t help you with this issue as far as I can see. Sorry!
    Your only option is to do what I did and switch to using Haskell ;-)

  2. Well, for starters, you’re using TBase without declaring it. It’s like saying that i = 1 ought to compile without an “int i” anywhere.
    Try this:
    public static void Do(this TBase value) where T : BaseClass

  3. Max, Stuart – Maybe I wasn’t clear enough in my post. I’m talking about a non-existent feature in C#, where I wouldn’t have to state TBase as a generic parameter, but that instead, one would be inferred for me. I was just looking for a reason for why this was never implemented. Maybe there’s a logical pitfall here somewhere…
    If there are none, I think this may be a strong candidate for a C# vNext feature.

  4. Internally, BaseClass needs to get mapped to an anonymous type after the TBase type is specified.
    If you don’t specify what TBase is, like you’re suggesting, the compiler doesn’t have enough information to know if you intend TBase to be a generic parameter or a class.
    Type inference is not magic.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s