仅当S和T不同时,才从λ表达式的输出推断出Func 的T?
当S
和T
不同时,这有效:
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或匿名方法的参数的值。 (或者,在out
和ref
forms参数的情况下,成为调用者提供的变量的别名。)forms参数是变量 ,因此具有类型 。
代表delegate R Func(A a);
具有类型A
forms参数a
。 使用方法类型参数构造它以使Func
,因此委托的forms参数类型现在是S
类型推断的任务是推断那些类型S
和T
在你的第一个例子中,你有一个lambda,其forms参数为string
类型。 因此类型推断的原因是,由于这个lambda参数对应于方法Fun
forms参数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
,我们显然不知道可能是什么,因此编译器不能仅基于此做出更多决策。