我有以下方法:
public static void Foo<T>(Predicate<T> validator) { ... }
我想这样调用它:
Foo(s => string.IsNullOrEmpty(s));
为什么编译器不能找出 s
是 string
,因此 T
是 string
?规范中的什么规则使推理算法在这里失败?
最佳答案
我承认我没有检查整个 C# 5.0 规范,但是 8.5.1 局部变量声明 部分谈到了 var
关键字,它用于声明一个推断类型。
以下是为 var
声明的变量和所有推断变量的规则:
- 局部变量声明不能包含多个局部变量声明符。
- local-variable-declarator 必须包含一个local-variable-initializer。
- local-variable-initializer 必须是一个表达式。
- 初始化器表达式 必须具有编译时类型。
- 初始化器表达式不能引用声明的变量本身
因为这是一个 lambda,所以您推断的初始值设定项是:
string.IsNullOrEmpty(s)
好的,所以...
- 它没有多个局部变量声明符。通过。
- 它包含一个 local-variable-intitalizer 因为它是一个 lambda。通过。
- 这是一个表达式。通过。
- string.IsNullOrEmpty 返回一个字符串。通过。
- 它依靠将自身传递给函数来确定类型。失败。
因此,要回答您的问题,您的初始化程序最终会失败,因为在将其传递给方法之前必须知道其类型。
不过,Lambda 可以相对轻松地解决这个问题:
Foo(string s => string.IsNullOrEmpty(s));
关于c# - 为什么编译器不推断泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39681795/