方法组重载决策与方法调用重载决策有何不同?

the*_*oop 6 c# overloading .net-4.0 covariance

以下代码不编译(error CS0123: No overload for 'System.Convert.ToString(object)' matches delegate 'System.Converter<T,string>'):

class A<T> {
    void Method(T obj) {
        Converter<T, string> toString = Convert.ToString;

        // this doesn't work either (on .NET 4):
        Converter<object, string> toString2 = Convert.ToString;
        Converter<T, string> toString3 = toString2;            
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这样做:

class A<T> {
    void Method(T obj) {
        // o is a T, and Convert.ToString(o) is using
        // string Convert.ToString(object o)

        Converter<T, string> toString = o => Convert.ToString(o);
    }
}
Run Code Online (Sandbox Code Playgroud)

在c#4中,可以将co/contra-variant代表彼此分配,并且可以使用co/contra-variant方法创建代理,因此该ToString(object)方法可以用作a Converter<T, string>,因为T始终保证可转换为a object.

因此,第一个示例(方法组重载决策)应该是找到唯一适用的方法string Convert.ToString(object o),与方法调用重载决策相同.为什么方法组和方法调用重载决策产生不同的结果?

Joã*_*elo 3

这与方差不适用于值类型这一事实有关,因此,如果您Twhere T : class获得方差一样进行限制T,则第一个代码片段将编译。

来自协方差和逆变常见问题解答

仅当类型参数是引用类型时才支持方差。值类型不支持方差。