Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does passing a method group to an overloaded method cause ambiguity when calling the method in a lambda does not in this case?

Why can't the correct overload to be called be inferred on the line marked // Compiler Error in the code below when the type is correctly inferred in all the other cases?

public static class Code {

    private static void Main() {

        OverloadedMethod<string>(() => new Wrapper<string>()); // OK
        OverloadedMethod<string>(() => MethodReturningWrappedString()); // OK
        OverloadedMethod<string>((Func<Wrapper<string>>)MethodReturningWrappedString); // OK
        OverloadedMethod<string>(MethodReturningWrappedString); // Compiler Error

    }

    public static Wrapper<string> MethodReturningWrappedString() {
        return new Wrapper<string>();
    }

    public static void OverloadedMethod<T>(Func<Wrapper<T>> func) where T : class {
    }

    public static void OverloadedMethod<T>(Func<T> func) where T : class {
    }

    public struct Wrapper<T> where T : class {
    }

}

Here's the compiler error:

The call is ambiguous between the following methods or properties:
'Namespace.Code.OverloadedMethod<string>(System.Func<Namespace.Code.Wrapper<string>>)'
and 'Namespace.Code.OverloadedMethod<string>(System.Func<string>)'
like image 407
Lawrence Johnston Avatar asked Jul 03 '14 22:07

Lawrence Johnston


1 Answers

Because the method group MethodReturningWrappedString can be converted to both a delegate of type Func<Wrapper<T>> and a delegate of type Func<U> for suitable values of T and U.

The overload resolution rules don't stipulate that the first conversion is strictly better than the second, so the conversion is ambiguous and results in a compiler error.

like image 196
Jon Avatar answered Nov 15 '22 00:11

Jon