为什么C#无法从非泛型静态方法的签名推断出泛型类型参数类型? [英] Why is C# unable to infer the generic type argument type from a non-generic static method's signature?

查看:92
本文介绍了为什么C#无法从非泛型静态方法的签名推断出泛型类型参数类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我进行了以下推理测试:

I have conducted the following inference tests:

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

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

The results seem to suggest that the C# compiler is unable to infer the generic type arguments for the delegate function parameters from a non-generic method group.

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

What puzzles me the most is that C# is can infer the type arguments for Func<T1, T2> from the method return values in ConsumeFunc1Func2, but is unable to infer the types for Func<T, T> in ConsumeFunc2c.

此问题类似于

This question is similar to the T of Func<S, T> is inferred from output of lambda expression only when S and T are different? question, but instead of lambdas with unknown parameter types we have non-generic method groups.

为什么不能C#从这种看似简单,显而易见的案例中得出的类型回答了以下问题:为什么无歧义的非泛型方法不足以进行推理?"和为什么参数类型和推断的返回值类型之间有区别?".

The Why can't C# infer type from this seemingly simple, obvious case question sort of answers the questions "Why are non-ambiguous non-generic methods not enough for inference?" and "Why is there a difference between the argument types and the return value type for inference?".

问题:

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

Why can the C# compiler infer the type of Func<T> using the type of the return value, but fails to see the success in the Func<T, T> case?

为什么C#编译器可以从ConsumeFunc1Func2中的Func<T1>推断Func<T1, T2>T1类型参数,却不能在ConsumeFunc2c中从自身推断出Func<T, T>T类型参数.更容易吗?

Why can the C# compiler infer the T1 type argument for Func<T1, T2> from the Func<T1> in ConsumeFunc1Func2, but cannot infer the T type argument for Func<T, T> from itself in ConsumeFunc2c which seems to be easier?

推荐答案

通常,方法名称不会唯一地标识可以向其分配方法组的唯一类型Action<T>.例如,即使仅Fred的一个重载并且仅使用一个Cat参数,该重载不仅可以分配给Action<Cat>,而且还可以分配给其他类型,例如Action<Mammal>Action<Animal>Action<Object>.尽管在某些情况下,一种类型替换在任何方面都将优于任何其他替换,但情况并非总是如此.定义语言以要求指定委托人的类型比让编译器尝试猜测"要干净得多,尤其是因为让编译器进行猜测将意味着很多本不应该破坏更改的事情将是(例如添加方法重载可能会使用于工作的类型推断变得含糊不清.

In general, a method name will not uniquely identify a unique type Action<T> to which the method group could be assigned. For example, even if there's only one overload of Fred and it takes a single Cat argument, that overload could be assigned not just to an Action<Cat>, but also to some other types like Action<Mammal>, Action<Animal>, or Action<Object>. While there are some cases where one type substitution would be in every way superior to any alternative, that is not always the case. It's cleaner to define the language to require that the type of delegate be specified, than to have the compiler try to "guess", especially since having the compiler guess would mean that many things which shouldn't be breaking changes, would be (e.g. adding a method overload may render ambiguous a type inference which used to work).

这篇关于为什么C#无法从非泛型静态方法的签名推断出泛型类型参数类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆