首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只有当S和T不同时,才能从λ表达式的输出中推断出Func<S、T>的T。

只有当S和T不同时,才能从λ表达式的输出中推断出Func<S、T>的T。
EN

Stack Overflow用户
提问于 2013-02-13 00:35:36
回答 2查看 1K关注 0票数 9

ST不同时,这是可行的:

代码语言:javascript
复制
public static void Fun<S, T>(Func<S, T> func)
{

}

Fun((string s) => true); //compiles, T is inferred from return type.

但,

代码语言:javascript
复制
public static void Fun<T>(Func<T, T> func)
{

}

Fun(t => true); //can't infer type.

在第一个例子中,既然T是从lambda表达式的返回类型中推断出来的,那么第二个例子中的T不能也被推断出来吗?我想它就是这样做的,但是为什么第一个T是未知的,而第二个T of Func<T, T>是已知的,毕竟T == T是对的?或者,在Func的情况下,推断的类型是否有顺序?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-13 01:08:35

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

在知道委托的形参类型之前,方法类型推断不会尝试从lambda推断委托的返回类型。

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

你说的“形参类型”是什么意思?

形参是一个变量,它接受传递给方法、索引器、构造器、lambda或匿名方法的实参的值。(或者,对于outref形式参数,将成为调用者提供的变量的别名。)形式参数是变量,因此具有类型。

委托delegate R Func<A, R>(A a);具有类型为A的形参a。您可以使用方法类型参数构造它来生成Func<S, T>,因此委托的形参类型现在是S。类型推断的任务是推断ST类型。

在第一个示例中,您有一个带有string类型的形参s的lambda。因此类型推断的原因是,由于此λ实参对应于方法Fun的形参func,并且func的形参类型为Func<S, T>,因此s的形参类型必须对应于S。由于您为s提供了正式的参数类型,因此S被推断为string

一旦做出了推断,就可以通过分析lambda的主体来推断T

在第二种情况下,没有为t指定正式的参数类型。因为没有其他方法可以推断t的类型,所以类型推断放弃了,在查看正文之前放弃了对这个lambda的分析。

碰巧在您的例子中,可以独立于lambda的形参类型来分析正文。这种情况很少见,类型推断算法并不是为了利用它而编写的。

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

票数 13
EN

Stack Overflow用户

发布于 2013-02-13 00:45:23

lambdas和其他函数的泛型参数由它们的参数类型决定,而不是由它们的返回类型决定。这就是为什么你不能这样做的原因:

代码语言:javascript
复制
T Foo<T>() { return default(T); }

string x = Foo(); // error

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14837286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档