0

With regard to the following extension methods:

public static class Extensions
{
    public static void P<T>(this T value) { }

    public static TResult F<T, TResult>(this T value)
    {
        return default(TResult);
    }
}

When I try to use these with various type parameter options, I get the following results:

1.P(); // Compiler just fine
1.P<int>(); // R# says "Type argument specification is redundant"
var x = 1.F<int, int>(); // Compiler just fine
var y = 1.F<int>(); // Compiler error: Incorrect number of type parameters

So how come the compiler can infer the type of T for P, yet cannot infer the same for F? What are the rules around such inference and is there a way I can avoid the need to specify the types like this?

David Arno
  • 42,717
  • 16
  • 86
  • 131
  • `this T value` is any type you pass. --> `1.P();` --> `1` is already integer – T.S. Jun 15 '15 at 19:23
  • @T.S., yes, I get that bit. What I don't understand is why that doesn't apply with `1.F`. Why is `int` inferred for `P` but not for `F`? – David Arno Jun 15 '15 at 19:27
  • You have completely different issue in `F` - it is a generic function that can't infer without mapping – T.S. Jun 15 '15 at 19:35
  • @T.S., I agree. Should I just delete this, or wait for it to be closed (I've voted it on it's way ;)? – David Arno Jun 15 '15 at 19:40
  • I don't know. I am not SO professional. Probably delete. – T.S. Jun 15 '15 at 19:41

1 Answers1

1

Section 7.5.2 of the C# 5.0 specs covers type inference, and goes through all of the rules that determine when type inference can and cannot succeed.

As for your two examples, the first case there is a parameter of a type that is being inferred, which allows it to be inferred, whereas in your second example you have a type argument that has no upper or lower bound, as none of the parameters use the type in any form, allowing upper or lower bounds to be applied to it.

Note that there is no way to infer some, but not all, of the generic type arguments of a method. Either they can all be inferred, or all must be explicitly provided, which is why you get an error when providing one generic type argument to a method expecting two, even though one of them could be inferred.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • 2
    What do you mean by *"has no upper or lower bound"*? – Yuval Itzchakov Jun 15 '15 at 19:25
  • @YuvalItzchakov The inference algorithm applies upper and lower bounds on the generic type arguments based on how they're used in the parameters, and type inference succeeds or fails based on what the bounds are on each of the type arguments. – Servy Jun 15 '15 at 19:28
  • FYI if you're using VS 2013 the spec is available on your PC at "Program Files (x86)\Microsoft Visual Studio 12.0\VC#\Specifications\1033" – DrewJordan Jun 15 '15 at 19:29
  • Still don't understand what those bounds represent. What does a bound mean logically in this context? – Yuval Itzchakov Jun 15 '15 at 19:29
  • @YuvalItzchakov Sounds like you need to just read the specs on type inference. I can't explain the entire type inference specs in the comments here. – Servy Jun 15 '15 at 19:31
  • @Servy, sorry but your second paragraph makes no sense to me at all. However, the third paragraph completely answers my question. Could you remove paragraph two please, or express it more clearly for us thickies, so I can accept this answer please? – David Arno Jun 15 '15 at 19:31