Why can't C# compiler infer generic-type delegate from function signature? [duplicate]

风格不统一 提交于 2019-11-29 13:47:54

I suppose it probably has something to do with the fact that, at least from the compiler's perspective, Test is actually a 'method group' until the compiler has determined what it types of parameters it will have. This is true even if there is only one method in the group (only one Test method in the current scope).

Observe:

var composed = Compose<object>(Test, () => Console.WriteLine(" world"));

yields the error:

The best overloaded method match for 'Compose<object>(System.Action<object>, System.Action)' has some invalid arguments

Argument 1: cannot convert from 'method group' to 'System.Action<object>'

But this is fine:

var composed = Compose<string>(Test, () => Console.WriteLine(" world"));

My guess is that the compiler see the both method group expression (Test) and implicitly typed generic method invocation (Compose) as 'unbound' in a sense. It can't fully determine which method to select from the method group from the type 'unbound' signature of the parameter to Compose, and it can't determine which the type type parameter for Compose from the signature. It needs one or the other to be 'bound' in order to compile the whole statement.

It might have to do with covariance. Although the type of the argument of Test is known, you might want to create a delegate of a more specific type.

public class BaseClass { }
public class DerivedClass : BaseClass { }

static class Program
{
    static void Main(string[] args)
    {
        var composed = Compose<DerivedClass>(Test, () => Console.WriteLine(" world"));
        composed(new DerivedClass());

        Console.ReadLine();
    }

    public static void Test(BaseClass arg)
    {
        Console.Write(arg);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!