3

See the following recent answer:

https://stackoverflow.com/a/36421418/1017882

To summarise, an extension method has been written that uses generics:

static TResult GetEntry<TEnum, TResult>(this Dictionary<TEnum, string> dictionary, TEnum key) {...}

All works fine when invoked like so:

var attributes = new Dictionary<MyTestEnum, string>();
var result = attributes.GetEntry<MyTestEnum, double>(MyTestEnum.First);

But if I invoke it differently:

var result = attributes.GetEntry(MyTestEnum.First);

Apparently the compiler can no longer infer the types. But it's very clear to see (based on what attributes is), what type I'm attempting to pass.

Why must I be explicit with what types I pass? It feels like unnecessary code.

Usually questions like this are answered with example usage that would 'break' without this kind of extra info - but I can't think of any scenarios like this.

Bit More Context

The reason I even tried drop that bit of syntax in the first place is because I (vaguely) recall being able to do so with certain generic uses. I wanted to see how it applies with collections like this.

Community
  • 1
  • 1
  • 6
    How should the compiler infer `TResult`? I don't think return types take part in generic inference anyway, so `string result = attributes.GetEntry(MyTestEnum.First)` won't work either. – Lee Apr 05 '16 at 12:16
  • @Lee - of course! I hadn't paid enough attention. I thought `TResult` was being passed as part of the extended parameter. –  Apr 05 '16 at 12:17

1 Answers1

5

But it's very clear to see (based on what attributes is), what type I'm attempting to pass.

But not how you are trying to pass it.

TResult does not depend on any of the types passed, so there's no way of knowing you want GetEntry<MyTestEnum, double> and not GetEntry<MyTestEnum, int> or GetEntry<MyTestEnum, MyTestEnum> or what have you.

There are times when a human using wider context than the compiler uses can see what is meant even when the compiler can't infer it, but this isn't one of those cases. I can only guess you probably want GetEntry<MyTestEnum, double> because that's the example you use earlier in your question.

If on the other hand you had something like:

public static TResult GetEntry<TKey, TResult>(Dictionary<TKey, TResult> dict, TKey key)
{
  return dict[key];
}

Then because all the type parameters relate to part of the signature of what it is called with, it would indeed be inferable, though there are still subtler cases where such inference can't happen.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • As per my comment to Lee, I'd missed this :( Good catch. +1. Thanks for the reply. –  Apr 05 '16 at 12:17