locked
Generic delegate as a method parameter RRS feed

  • Question


  • Code Snippet

    class Program

    {

    public delegate T Func<T>(T t);


    static public void SomeMethod<T>(Func<T> f) {}

    static public int MyDelegate(int i) {return 0;}

    static public void Main() {SomeMethod(MyDelegate);}

    }


    Above is the smallest code snippet that illustrates an issue I'm coming up with concerning generic delegates. When I attempt to build the above program, I get an error:

    The type arguments for method 'Program.SomeMethod<T>(Program.Func<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

    Why is this? I should hope that it's quite clear what T should be, since MyDelegate accepts an int as a parameter and returns an int. What is it about this example that causes ambiguity?
    Thursday, May 22, 2008 8:28 PM

Answers

All replies

  • It's a limitation of the compiler. A detailed technical explanation can be found here:

     

    http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx

     

    If you assign the delegate to a variable first, it does work:

     

    Code Snippet

    static public void Main()

    {

       Func<int> method = MyDelegate;

     

       SomeMethod(method);

    }

     

     

    Thursday, May 22, 2008 8:53 PM
  • I'm actually working in C# 2.0, but I see how that article applies to my example. I suppose I can see what it's trying to say, but look at the following code sample. This example is closer to the actual snippet from my project.

    Code Snippet

    class Program

    {

    public delegate T Func<T>(T t);


    static public void SomeMethod<TList, T>(Func<T> f, TList list) where TList : IList<T>, new() {}


    static public int MyDelegate(int i) {return 0;}


    static public void Main() {SomeMethod(MyDelegate, new List<int>());}

    }


    This code sample produces the same error, and yet with the addition of the second parameter to SomeMethod, it becomes unambiguous that T must be int, since TList is required to be derived from IList<T>, and I explicitly specify the second parameter as a List<int>. Is there a more explicit way to specify the type parameters without forcing the caller to do it?
    Thursday, May 22, 2008 9:17 PM
  •  Rainault wrote:
    This code sample produces the same error, and yet with the addition of the second parameter to SomeMethod, it becomes unambiguous that T must be int, since TList is required to be derived from IList<T>, and I explicitly specify the second parameter as a List<int>. Is there a more explicit way to specify the type parameters without forcing the caller to do it?

     

    I'm afraid not. Whenever there's a generic delegate involved in the parameter list, type inference fails...

    Thursday, May 22, 2008 9:52 PM
  • Blarg. :\ Well, thanks for the link to that article. I appreciate the help.
    Thursday, May 22, 2008 11:24 PM