简体   繁体   English

为什么编译器不推断泛型类型

[英]Why does the compiler not infer the generic type

I have the following method:我有以下方法:

public static void Foo<T>(Predicate<T> validator) { ... }

And I want to call it the following way:我想这样称呼它:

Foo(s => string.IsNullOrEmpty(s));

Why can't the compiler figure out s is string and therefore T is string ?为什么编译器不能确定sstring ,因此Tstring What rule in the spec makes the inference algorithm fail here?规范中的什么规则使推理算法在这里失败?

I admit I haven't checked the entire C# 5.0 specification, but section 8.5.1 Local variable declarations talks a bit about the var keyword, which is used to declare an inferred type.我承认我没有检查整个 C# 5.0 规范,但是8.5.1 局部变量声明部分谈到了var关键字,它用于声明推断类型。

Here are the rules for variables declared for var and for all inferred variables:以下是为var和所有推断变量声明的变量的规则:

  • The local-variable-declaration cannot include multiple local-variable-declarators.局部变量声明不能包含多个局部变量声明符。
  • The local-variable-declarator must include a local-variable-initializer. local-variable-declarator 必须包含一个 local-variable-initializer。
  • The local-variable-initializer must be an expression.局部变量初始值设定项必须是一个表达式。
  • The initializer expression must have a compile-time type.初始值设定项表达式必须具有编译时类型。
  • The initializer expression cannot refer to the declared variable itself初始化表达式不能引用声明的变量本身

Because this is a lambda, your inferred initializer is:因为这是一个 lambda,所以您推断的初始化程序是:

string.IsNullOrEmpty(s)

OK, so...好的,那么...

  • It doesn't have multiple local-variable-declarators.它没有多个局部变量声明符。 Pass.经过。
  • It includes a local-variable-intitalizer because it's a lambda.它包括一个局部变量初始化器,因为它是一个 lambda。 Pass.经过。
  • It's an expression.是一种表达。 Pass.经过。
  • string.IsNullOrEmpty returns a string. string.IsNullOrEmpty 返回一个字符串。 Pass.经过。
  • It relies on itself being passed to a function to determine the type.它依赖于传递给函数的自身来确定类型。 Fail.失败。

So, to answer your question, your initializer ultimately fails because its type must be known before you can pass it to a method.因此,为了回答您的问题,您的初始化程序最终会失败,因为在将其传递给方法之前必须知道其类型。

Lambdas can fix this relatively easily, though:不过,Lambda 可以相对轻松地解决这个问题:

Foo(string s => string.IsNullOrEmpty(s));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么编译器有时不能隐式推断出包含泛型类型的返回类型? - Why can the compiler sometimes not implicitly infer the return type that contains the generic type? 为什么我必须显式提供泛型参数类型而编译器应该推断类型? - Why must I provide explicitly generic parameter types While the compiler should infer the type? 为什么编译器无法推断出对象数组类型? - Why Compiler cannot infer the object array type? 编译器无法从包装的通用 IEnumerable 推断类型 - Compiler cannot infer type from wrapped generic IEnumerable 推断接口的通用类型 - Infer Generic Type of Interface 编译器如何从LAMBDA表达式推断出委托类型? - How does compiler infer the delegate type from LAMBDA expression? 为什么编译器不能为自定义集合推断循环变量类型? - Why compiler can not infer loop variable type for custom collections? 为什么编译器不能推断出这个select调用的类型? - Why can't the compiler infer the type for this select call? 为什么编译器不能从使用中推断出这种类型的参数 - Why can't the compiler infer this type argument from usage 为什么编译器不能为我推断类型? (又名Smarter SmartEnumerable) - Why cant the compiler infer the type for me? (aka Smarter SmartEnumerable)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM