为什么C#无法从非泛型静态方法的签名推断泛型类型参数类型?

Ark*_*kun 11 c# generics type-inference

我进行了以下推理测试:

static class InferenceTest {
    static void TakeInt(int a) { }
    static int GiveInt() { return 0; }
    static int TakeAndGiveInt(int a) { return 0; }

    static void ConsumeAction1<T>(Action<T> a) { }
    static void ConsumeFunc1<T>(Func<T> f) { }
    static void ConsumeFunc2a<T1, T2>(Func<T1, T2> f) { }
    static void ConsumeFunc2b<T>(Func<int, T> f) { }
    static void ConsumeFunc2c<T>(Func<T, T> f) { }
    static void ConsumeFunc1Func2<T1, T2>(Func<T1> f1, Func<T1, T2> f2) { }

    static void Main() {
        ConsumeAction1(TakeInt);        //error
        ConsumeFunc1(GiveInt);          //ok
        ConsumeFunc2a(TakeAndGiveInt);  //error
        ConsumeFunc2b(TakeAndGiveInt);  //ok
        ConsumeFunc2c(TakeAndGiveInt);  //error
        ConsumeFunc1Func2(GiveInt, TakeAndGiveInt); //ok
    }
}
Run Code Online (Sandbox Code Playgroud)

结果似乎表明C#编译器无法从非泛型方法组推断委托函数参数的泛型类型参数.

最让我困惑的是C#可以Func<T1, T2>从方法返回值中推断出类型参数ConsumeFunc1Func2,但是无法推断出Func<T, T>in 的类型ConsumeFunc2c.

这个问题类似于F的函数<S,T>只有当S和T不同时才从lambda表达式的输出中推断出来?问题,但我们有非通用的方法组,而不是具有未知参数类型的lambda.

为什么可以从这个看似简单的,明显的情况下,不C#推断型的问题排序回答的问题:"为什么无歧义的非通用方法不够的推论?" 和"为什么参数类型和推理的返回值类型之间存在差异?".

问题:

为什么C#编译器可以推断出Func<T>使用返回值类型的类型,但是在这种Func<T, T>情况下看不到成功?

为什么C#编译器推断T1类型参数为Func<T1, T2>Func<T1>ConsumeFunc1Func2,但不能推断T类型参数Func<T, T>从本身ConsumeFunc2c这似乎是更容易?

Mau*_*tro 1

不检查方法参数。

正如所建议的,在 ConsumeFunc1Func2 中,编译器仅根据返回值进行推断。在 ConsumeFunc2c 中,不会检查 TakeAndGiveInt 签名以查看其方法参数类型实际上是否与方法返回类型相同,因为...方法参数未检查!