type argument from Action<T> cannot be inferred, but from Func<T> can be

c#, delegates, generics

Solution

Methods can be overloaded by their arguments and all overloads form one method group, so for example `void Xyz(int i)` and `void Xyz(string s)` are within same method group called `Xyz`. Compiler is not able to deduct a type of argument even if user defines only one method, because behaviour of compiler is quite strict.

Methods can't be overloaded by return types, so you can't have `int Xyz()` and `string Xyz()` within same class. Return type can be deducted by compiler easily, because there is no overloading.

It was not obvious for me for the first time, but it has been quite clear after I realized that I could create an overload.

Problem

I've been playing a little with generics and delegates and I have found something I don't understand. I have quite similar generic static methods, one accepts `Action<T>` and the second one accepts `Func<T>`. Now the problem: if I call the one accepting `Func<T>` without explicit Type, compiler is fine with that. But with the one accepting `Action<T>` my program can't be compiled (see the code for error message). My question is: Why is compiler able to recognize return type, but is not able to recognize argument type? ``` public interface IMessage { } public class Message : IMessage { } ``` ``` static void HandleAction<TMessage>(Action<TMessage> action) where TMessage : IMessage { } static void HandleFunction<TMessage>(Func<TMessage> action) where TMessage : IMessage { } static void A(Message message) { } static Message F() { return new Message(); } static void Main(string[] args) { // this one is ok HandleFunction(F); // compiler error: // The type arguments for method // 'template_test.Program.HandleAction<TMessage>(System.Action<TMessage>)' // cannot be inferred from the usage. //Try specifying the type arguments explicitly. //HandleAction(A); // this one is ok HandleAction<Message>(A); } ``` I'm using .NET 4.5 in Visual Studio 2012.

Original source

Related problems