这与 S 和 T 的不同无关。它与您在第一种情况下提供形式参数类型有关,而在第二种情况下不提供它。
方法类型推断不会尝试从 lambda 推断委托的返回类型直到知道委托的形式参数类型.
在第二种情况下,您没有给编译器任何东西来推断形式参数类型 T,因此 lambda 的主体甚至不会被分析。
“形式参数类型”是什么意思?
形式参数是一个变量,它接受传递给方法、索引器、构造函数、lambda 或匿名方法的参数值。 (或者,在以下情况下out
and ref
形式参数,成为调用者提供的变量的别名。)形式参数是变量,因此有types.
代表delegate R Func<A, R>(A a);
有形式参数a
与类型A
。您可以使用方法类型参数来构造它Func<S, T>
,所以委托的形参类型现在是S
。类型推断的任务就是推断那些类型S
and T
.
在你的第一个例子中,你有一个带有形式参数的 lambdas
类型的string
。所以类型推断的原因是,由于这个 lambda 参数对应于形式参数func
方法的Fun
,以及形式参数类型func
is Func<S, T>
那么形式参数类型s
必须对应于S
。由于您给出了形式参数类型s
, S
被推断为string
.
一旦做出这样的推论T
可以通过分析 lambda 的主体来推断。
在第二种情况下,没有给出正式的参数类型t
。由于没有其他任何东西可以从中得出类型t
可以推断,类型推断放弃并放弃在查看主体之前分析此 lambda。
碰巧的是,在您的情况下,可以独立于 lambda 的形式参数类型来分析主体。这是一种罕见的情况,类型推断算法并不是为了利用它而编写的。
如果这是您想要的类型推断,请考虑使用 F# 而不是 C#。它具有基于 Hindley-Milner 算法的更先进的类型推断算法。