当S和T不同时,这是可行的:
public static void Fun<S, T>(Func<S, T> func)
{
}
Fun((string s) => true); //compiles, T is inferred from return type.但,
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的情况下,推断的类型是否有顺序?
发布于 2013-02-13 01:08:35
这与S和T是不同的没有任何关系。这与您在第一种情况下提供形参类型,而在第二种情况下不提供形参类型有关。
在知道委托的形参类型之前,方法类型推断不会尝试从lambda推断委托的返回类型。
在第二种情况下,您没有给编译器任何东西来推断形参类型T,因此甚至不会分析lambda的主体。
你说的“形参类型”是什么意思?
形参是一个变量,它接受传递给方法、索引器、构造器、lambda或匿名方法的实参的值。(或者,对于out和ref形式参数,将成为调用者提供的变量的别名。)形式参数是变量,因此具有类型。
委托delegate R Func<A, R>(A a);具有类型为A的形参a。您可以使用方法类型参数构造它来生成Func<S, T>,因此委托的形参类型现在是S。类型推断的任务是推断S和T类型。
在第一个示例中,您有一个带有string类型的形参s的lambda。因此类型推断的原因是,由于此λ实参对应于方法Fun的形参func,并且func的形参类型为Func<S, T>,因此s的形参类型必须对应于S。由于您为s提供了正式的参数类型,因此S被推断为string。
一旦做出了推断,就可以通过分析lambda的主体来推断T。
在第二种情况下,没有为t指定正式的参数类型。因为没有其他方法可以推断t的类型,所以类型推断放弃了,在查看正文之前放弃了对这个lambda的分析。
碰巧在您的例子中,可以独立于lambda的形参类型来分析正文。这种情况很少见,类型推断算法并不是为了利用它而编写的。
如果这是您想要的类型推断,请考虑使用F#而不是C#。它有一个基于Hindley-Milner算法的更高级的类型推理算法。
发布于 2013-02-13 00:45:23
lambdas和其他函数的泛型参数由它们的参数类型决定,而不是由它们的返回类型决定。这就是为什么你不能这样做的原因:
T Foo<T>() { return default(T); }
string x = Foo(); // error对于表达式t => true,我们显然不知道t可能是什么,因此编译器不能仅基于此做出更多决定。
https://stackoverflow.com/questions/14837286
复制相似问题