C# 3.0 generic type inference - passing a delegate as a function parameter

c#, c#-3.0, delegates, generics, type-inference

Solution

Maybe this will make it clearer:

public class SomeClass
{
    static void foo(int x) { }
    static void foo(string s) { }
    static void bar<T>(Action<T> f){}
    static void barz(Action<int> f) { }
    static void test()
    {
        Action<int> f = foo;
        bar(f);
        barz(foo);
        bar(foo);
        //these help the compiler to know which types to use
        bar<int>(foo);
        bar( (int i) => foo(i));
    }
}

foo is not an action - foo is a method group.

- In the assignment statement, the compiler can tell clearly which foo you're talking about, since the int type is specified.

- In the barz(foo) statement, the compiler can tell which foo you're talking about, since the int type is specified.

- In the bar(foo) statement, it could be any foo with a single parameter - so the compiler gives up.

Edit: I've added two (more) ways to help the compiler figure out the type (ie - how to skip the inference steps).

From my reading of the article in JSkeet's answer, the decision to not infer the type seems to be based on a mutual infering scenario, such as

  static void foo<T>(T x) { }
  static void bar<T>(Action<T> f) { }
  static void test()
  {
    bar(foo); //wut's T?
  }

Since the general problem was unsolve-able, they choose to left specific problems where a solution exists as unsolved.

As a consequence of this decision, you won't be adding a overload for a method and getting a whole lot of type confusion from all the callers that are used to a single member method group. I guess that's a good thing.

Problem

I am wondering why the C# 3.0 compiler is unable to infer the type of a method when it is passed as a parameter to a generic function when it can implicitly create a delegate for the same method. Here is an example: ``` class Test { static void foo(int x) { } static void bar<T>(Action<T> f) { } static void test() { Action<int> f = foo; // I can do this bar(f); // and then do this bar(foo); // but this does not work } } ``` I would have thought that I would be able to pass `foo` to `bar` and have the compiler infer the type of `Action<T>` from the signature of the function being passed but this does not work. However I can create an `Action<int>` from `foo` without casting so is there a legitimate reason that the compiler could not also do the same thing via type inference?

Original source