3

Why do I get ambiguous call error between (Func<IInterface>) and (Func<Task<IInterface>>) for the next code sample? And how can I avoid this error without replacing method group call?

public class Program
{
    public static void Main(string[] args)
    {
        Method(GetObject);
    }

    public static IInterface GetObject() => null;

    public static void Method(Func<IInterface> func) => 
        Console.WriteLine("First");

    public static void Method(Func<Task<IInterface>> funcAsync) => 
        Console.WriteLine("Second");
 }

 public interface IInterface { }
  • 3
    to "fix" it: `Method((Func)GetObject);` or (actually slightly more efficient in some ways. because the compiler caches the delegate instance in a static field): `Method(() => GetObject());` – Marc Gravell Jul 28 '17 at 12:11
  • 2
    `GetObject` is a method group in this call, a mystical creature that exists in C# seemingly only [to trip up overload resolution on delegates](https://stackoverflow.com/questions/2057146/). (Specifically, "overload resolution does not consider return types".) – Jeroen Mostert Jul 28 '17 at 12:52
  • Now that you've amended your question to "without replacing method group call", the answer is a really simple "you can't". The only option left is to rename one of the `Method`s (`MethodAsync` has a nice ring to it) so you don't run afoul of overloading in the first place. (I suppose raising on issue on the Roslyn repository to have the C# language changed is another option, but I don't give that much chance of success.) Overload resolution simply cannot distinguish between these two methods when you use a method group. – Jeroen Mostert Jul 28 '17 at 13:38

1 Answers1

1

This will fix the issue as your method expects a function that returns IInterface

public class Program
{
    public static void Main(string[] args)
    {
        Method(() => GetObject());
    }

    public static IInterface GetObject() => null;

    public static void Method(Func<IInterface> func) =>
        Console.WriteLine("First");

    public static void Method(Func<Task<IInterface>> funcAsync) =>
        Console.WriteLine("Second");
}

public interface IInterface { }
ogomrub
  • 146
  • 2
  • 7