5

I have this simple piece of code:

class Program
{
    static void test<T1>(Action<T1> action) { }

    static void test<T1, T2>(Action<T1, T2> action) {  }

    static void B(int a) { }
    static void C(string a, int b) { }

    static void Main(string[] args)
    {
        test(B);
        test(C);
    }
}

which does not compile because of two errors :

The type arguments for method 'Program.test<T1>(Action<T1>)' cannot be
inferred from the usage. Try specifying the type arguments explicitly.
The type arguments for method 'Program.test<T1>(Action<T1>)' cannot be
inferred from the usage. Try specifying the type arguments explicitly.

Of course it works if I explicitely specify the type parameters.

test<int>(B);

or if I cast B to the proper Action type:

test((Action<int>) B)

I would rather have an elegant solution where the C# compiler identifies the correct method overload automatically.

Is this only possible?

Regis Portalez
  • 4,675
  • 1
  • 29
  • 41
  • 1
    You have to explicitly specify the type parameter if it is not used in a parameter. – Stefan Sep 26 '19 at 09:28
  • @Stefan The point is that it *is* used in a parameter... (or at least it seems so) – DavidG Sep 26 '19 at 09:31
  • 1
    B and C are method groups not Actions etc you can cast them though: test((Action)B); test((Action)C); BUt i don't think that helps you much – Tim Rutter Sep 26 '19 at 09:33
  • [This page](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#type-inference) might tell you why this happens, but it's quite a tough read... – Sweeper Sep 26 '19 at 09:35
  • @DavidG It isn't. The parameter type is `Action` and not `T1` – Stefan Sep 26 '19 at 09:36
  • @Stefan Yes, but if you had a variable of type `Action` instead of using a method group syntax like above, the type would be inferred correctly. – DavidG Sep 26 '19 at 09:43
  • @DavidG So if in this example the method B() is casted to an Action it would work? – Stefan Sep 26 '19 at 09:48
  • 1
    @Stefan Yes, you could do `Action b = x => B(x);` and then `test(b);` – DavidG Sep 26 '19 at 09:48
  • @DavidG That sounds like an answer OP can use. And thanks for the info, I'm a little smarter now too. – Stefan Sep 26 '19 at 10:05

0 Answers0