为什么编译器不推断泛型类型
Why does the compiler not infer the generic type
我有以下方法:
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
声明的变量和所有推断变量的规则:
- 局部变量声明不能包含多个局部变量声明符。
- 局部变量声明符必须包含局部变量初始化器。
- 局部变量初始化器必须是表达式。
- 初始化程序 表达式 必须具有编译时类型。
- 初始化器表达式不能引用声明的变量本身
因为这是一个 lambda,所以您推断的初始化程序是:
string.IsNullOrEmpty(s)
好的,所以...
- 它没有多个局部变量声明符。通过.
- 它包含一个 local-variable-intitalizer 因为它是一个 lambda。通过.
- 这是一个表达式。通过.
- string.IsNullOrEmpty returns 一个字符串。通过.
- 它依靠自身传递给函数来确定类型。失败。
因此,要回答您的问题,您的初始化程序最终会失败,因为在将其传递给方法之前必须知道其类型。
Lambdas 可以相对容易地解决这个问题,不过:
Foo(string s => string.IsNullOrEmpty(s));
我有以下方法:
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
声明的变量和所有推断变量的规则:
- 局部变量声明不能包含多个局部变量声明符。
- 局部变量声明符必须包含局部变量初始化器。
- 局部变量初始化器必须是表达式。
- 初始化程序 表达式 必须具有编译时类型。
- 初始化器表达式不能引用声明的变量本身
因为这是一个 lambda,所以您推断的初始化程序是:
string.IsNullOrEmpty(s)
好的,所以...
- 它没有多个局部变量声明符。通过.
- 它包含一个 local-variable-intitalizer 因为它是一个 lambda。通过.
- 这是一个表达式。通过.
- string.IsNullOrEmpty returns 一个字符串。通过.
- 它依靠自身传递给函数来确定类型。失败。
因此,要回答您的问题,您的初始化程序最终会失败,因为在将其传递给方法之前必须知道其类型。
Lambdas 可以相对容易地解决这个问题,不过:
Foo(string s => string.IsNullOrEmpty(s));