为什么将方法组传递给重载方法会导致歧义,而在lambda中调用该方法则不会

本文关键字:方法 lambda 而在 调用 歧义 为什么 重载 | 更新日期: 2023-09-27 18:11:34

为什么不能在下面代码中标记为// Compiler Error的行上推断出正确的要调用的重载,而在所有其他情况下都可以正确推断类型?

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 {
    }
}

下面是编译错误:

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>)'

为什么将方法组传递给重载方法会导致歧义,而在lambda中调用该方法则不会

因为方法组MethodReturningWrappedString可以在适当的TU值下转换为Func<Wrapper<T>>类型的委托和Func<U>类型的委托。

重载解析规则没有规定第一次转换严格优于第二次转换,因此转换是不明确的,会导致编译器错误。