Func<;S、 T>;仅当S和T不同时,才从lambda表达式的输出推断
本文关键字:表达式 lambda 才从 输出 gt lt 仅当 Func | 更新日期: 2023-09-27 17:59:00
当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
是未知的,而Func<T, T>
的第二个T
是已知的,毕竟T == T
是对的?或者,在Func
s的情况下,是否有推断类型的顺序?
这与S和T的不同无关。这与在第一种情况下提供形式参数类型有关,而在第二种情况下不提供。
方法类型推断不会尝试从lambda推断委托的返回类型,直到该委托的形式参数类型为已知为止。
在第二种情况下,您没有给编译器任何信息来推断形式参数类型T,因此lambda的主体甚至不会被分析。
你所说的"形式参数类型"是什么意思?
形式参数是一个变量,它接受传递给方法、索引器、构造函数、lambda或匿名方法的参数值。(或者,在out
和ref
的情况下,形式参数成为调用方提供的变量的别名。)形式参数是变量,因此具有类型。
委托delegate R Func<A, R>(A a);
具有类型为A
的形式参数a
。您使用方法类型参数构造它,使其成为Func<S, T>
,因此委托的形式参数类型现在是S
。类型推断的任务是推断出CCD_ 17和CCD_。
在第一个示例中,您有一个lambda,其形式参数s
的类型为string
。因此类型推断的原因是,由于这个lambda参数对应于方法Fun
的形式参数func
,并且func
的形式参数类型是Func<S, T>
,那么s
的形式参数必须对应于S
。由于您为s
提供了一个形式化的参数类型,因此S
被推断为string
。
一旦进行了该推断,则可以通过分析lambda的主体来推断CCD_ 30。
在第二种情况下,没有为t
提供正式的参数类型。由于没有其他东西可以推断出t
的类型,因此类型推断放弃并放弃在查看主体之前分析该lambda。
恰好在您的情况下,可以独立于lambda的形式参数类型来分析主体。这是一种罕见的情况,类型推理算法并不是为了利用它而编写的
如果这是您想要的类型推断,请考虑使用F#而不是C#。它有一个更先进的类型推理算法,基于Hindley-Milner算法。
lambda和其他函数的泛型参数是由它们的参数类型决定的,而不是由它们的返回类型决定的。这与你不能这样做的原因完全相同:
T Foo<T>() { return default(T); }
string x = Foo(); // error
对于表达式t => true
,我们显然不知道t
可能是什么,因此编译器不能仅基于此做出任何决策。