仅当S和T不同时,才从λ表达式的输出推断出Func 的T?

ST不同时,这有效:

 public static void Fun(Func func) { } Fun((string s) => true); //compiles, T is inferred from return type. 

但,

 public static void Fun(Func func) { } Fun(t => true); //can't infer type. 

在第一个例子中,由于T是从lambda表达式的返回类型推断的,所以第二个例子中的T也不能被推断出来吗? 我想它是这样做的,但是为什么第一个T未知,当Func第二个T已知时,毕竟T == T对吗? 或者在Func的情况下是否有推断类型的订单?

它与S和T不同,没有任何关系。 它与您在第一种情况下提供forms参数类型而在第二种情况下不提供它有关。

方法类型推断不会尝试从lambda推断委托的返回类型, 直到知道委托的forms参数类型为止

在第二种情况下,你没有给编译器任何推断forms参数类型T的东西,因此甚至不会分析lambda的主体。

“forms参数类型”是什么意思?

forms参数是一个变量,它接受传递给方法,索引器,构造函数,lambda或匿名方法的参数的值。 (或者,在outrefforms参数的情况下,成为调用者提供的变量的别名。)forms参数是变量 ,因此具有类型

代表delegate R Func(A a); 具有类型Aforms参数a 。 使用方法类型参数构造它以使Func ,因此委托的forms参数类型现在是S 类型推断的任务是推断那些类型ST

在你的第一个例子中,你有一个lambda,其forms参数为string类型。 因此类型推断的原因是,由于这个lambda参数对应于方法Funforms参数func ,而func的forms参数类型是Func ,因此s的forms参数类型必须对应于S 由于您为s提供了forms参数类型,因此S被推断为string

一旦做出推断,则可以通过分析λ的主体来推断T

在第二种情况下,没有给出t正式参数类型。 由于没有其他任何东西可以从中推导出t的类型,因此在查看正文之前,类型推断会放弃并放弃分析此lambda。

恰好在你的情况下,可以独立于lambda的forms参数类型来分析主体。 这是一种罕见的情况,并且没有编写类型推断算法来利用它。

如果这是您想要的类型推断,请考虑使用F#而不是C#。 它具有更先进的类型推断算法,基于Hindley-Milner算法。

lambdas和其他函数的通用参数由它们的参数类型决定,而不是它们的返回类型。 这与你不能这样做的原因完全相同:

 T Foo() { return default(T); } string x = Foo(); // error 

对于表达式t => true ,我们显然不知道可能是什么,因此编译器不能仅基于此做出更多决策。