In my application, I have code similar to following:
class Program
{
static void Main(string[] args)
{
Method(uri => Task.FromResult(uri));
}
static void Method(Func<Uri, Uri> transformer)
{
throw new NotImplementedException();
}
static void Method(Func<Uri, Task<Uri>> transformer)
{
throw new NotImplementedException();
}
}
As expected, running this code calls the second overload of 'Method', the one expecting a function delegate that returns a task. However, if i change the code to avoid using the anonymous method in Main:
class Program
{
static void Main(string[] args)
{
Method(Method2);
}
static Task<Uri> Method2(Uri uri)
{
return Task.FromResult(uri);
}
static void Method(Func<Uri, Uri> transformer)
{
throw new NotImplementedException();
}
static void Method(Func<Uri, Task<Uri>> transformer)
{
throw new NotImplementedException();
}
}
The C# compiler now complains that my call to 'Method' is ambiguous. What am i missing?
The long answer is at https://stackoverflow.com/a/2058854/1223597 (as richzilla pointed out).
The short answer is that the C# compiler team chose to make method group conversions (like Method(Method2)
) ignore the return type (here of Method2
). This gives them flexibility in how Expression
trees are parsed. Unfortunately that means the compiler cannot implicitly choose between your 2 Method
signatures.
When doing a lambda conversion, (Method(uri => Task.FromResult(uri))
), the compiler team doesn't need to worry about expression tree parsing, so they do consider return types.