Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this method invocation ambiguous?

Tags:

c#

roslyn

c#-7.2

Why does the first call to Foo below compile but the second one results in an ambiguous invocation compiler error?

(using c# 7.2)

    private static void AmbiguousAsyncOverload() {
      Foo(() => Bar());  // This is OK
      //Foo(Bar);        // Error, ambiguous overload
    }

    private static void Foo(Func<int> func) {
      func();
    }

    private static void Foo(Func<string> func) {
      func();
    }

    private static int Bar() {
      return 4;
    }

If I remove the first (Func<int>) implementation of Foo, and hence the possibility of ambiguity, then the compiler (correctly) reports that Bar doesn't have the correct signature to be passed into Foo, which implies it has enough information to resolve the ambiguity.

I would understand if the compiler didn't look at return values during overload resolution and therefore both calls failed, but my question is why does one call compile ok while the other doesn't.

like image 826
eoinmullan Avatar asked Jul 09 '19 11:07

eoinmullan


People also ask

What is an ambiguous invocation?

Ambiguous Invocation. □ Sometimes there may be two or more possible. matches for an invocation of a method, but the. compiler cannot determine the most specific match. This is referred to as ambiguous invocation.

What is ambiguous method?

This ambiguous method call error always comes with method overloading where compiler fails to find out which of the overloaded method should be used. Suppose we have a java program like below. Above program compiles perfectly and when we run it, it prints “String”. So the method foo(String s) was called by the program.

What does ambiguous mean in Java?

The ambiguities are those issues that are not defined clearly in the Java language specification. The different results produced by different compilers on several example programs support our observations.

What is ambiguity error in method overloading?

Ambiguity errors occur when erasure causes two seemingly distinct generic declarations to resolve to the same erased type, causing a conflict. Here is an example that involves method overloading. In this case, Java uses the type difference to determine which overloaded method to call.


1 Answers

This was an issue for all versions of C# up until it was fixed in v7.3. Return types were not taken into account during overload resolution. From the release notes (or the language proposal) for C# 7.3:

  1. For a method group conversion, candidate methods whose return type doesn't match up with the delegate's return type are removed from the set.
like image 147
DavidG Avatar answered Oct 03 '22 13:10

DavidG