为什么不能推断出这些泛型类型?
本文关键字:泛型类型 不能 推断出 为什么 | 更新日期: 2023-09-27 18:17:20
我有以下代码:
public static class CardView {
public static object Column<TModel, TResult>(Func<TModel, TResult> field) {
return null;
}
}
public class Person
{
public string Name { get; set; }
public bool Gender { get; set; }
}
void Main()
{
var model = new Person() { Name = "Andre", Gender = true };
var b = CardView.Column(model => model.Name); // ERROR
// The type arguments for method 'UserQuery.CardView.Column<TModel,TResult>(System.Func<TModel,TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
}
由于某些原因,它不能推断出Column
方法的泛型类型。我要知道原因。我不能放弃类型推断而自己指定类型,因为这只是一个大问题的案例研究,在这个问题中它是必不可少的。
编辑
我拼错了代码=/只是修复它
为了让编译器执行类型推断,必须给它某种类型信息。在这个场景中,它提供的唯一信息是一个未类型化的lambda表达式。编译器在这里没有什么可做的。
有几种方法可以解决这个问题。最简单的方法是向lambda参数
添加类型var b = CardView.Column((Person m) => m.Name);
技术上的答案是"因为规范没有说你可以这样做"。引用规范第7.5.2节(类型推断):
7.5.2.1第一阶段对于每个方法参数Ei:
- 如果Ei是一个匿名函数,一个显式的参数类型推断(§7.5.2.7)由Ei制成Ti
- 否则,如果Ei有类型U和xi是一个值参数,那么从U到Ti。
- 如果Ei类型为U,且xi为ref/out形参然后从U到Ti得到一个精确的推断。
- 否则,对该参数不做任何推断。
:
7.5.2.7显式参数类型推断
从表达式E到类型T进行显式参数类型推断方法:
- 如果E是参数类型为U1…Uk的显式匿名函数,T是带参数的委托类型或表达式树类型类型V1…Vk则对每个Ui进行精确推断(§7.5.2.8)从Ui到相应的Vi。
由于示例中的匿名函数没有显式键入,因此无法进行推断。这也告诉我们,要进行推断,您可以通过指定函数的类型来提供帮助:
var b = CardView.Column((Person m) => m.Name);
现在这是一个显式的Func<Person, string>
,所以推理是成功的。
在该方法签名中没有TModel
参数(或使用TModel
的泛型类型),因此编译器不知道m
的类型
您编辑的代码无法编译。不能使用model
作为lambda参数,因为已经将其声明为局部变量。您似乎希望通过使用已经声明的该类型的局部变量来告诉编译器lambda参数是Person
。但这行不通。
告知编译器该类型的正确方法是在lambda中显式声明它,就像其他人所说的:
var b = CardView.Column((Person m) => m.Name);
或为泛型方法提供类型参数:
var b = CardView.Column<Person, string>(m => m.Name);