假设我有一个 POCO 和一个 List 类:class MyClass{...}class MyClasses : List<MyClass> {...}IEnumerable<MyClass>以及将 an 映射到列表的以下方法MyClasses:public static TListType ToListOfType<TListType, TItemType>(this IEnumerable<TItemType> list) where TListType : IList<TItemType>, new(){ var ret = new TListType(); foreach (var item in list) { ret.Add(item); } return ret;}我希望这段代码能够编译,但事实并非如此:var list = someListOfMyClass.ToListOfType<MyClasses>();但我得到错误 CS1061“IEnumerable”不包含“ToListOfType”的定义,并且找不到接受“IEnumerable”类型的第一个参数的可访问扩展方法“ToListOfType”(您是否缺少 using 指令或程序集引用?)然而,这确实有效:var list = someListOfMyClass.ToListOfType<MyClasses, MyClass>();我不明白为什么类型推断不足以让编译器知道项目类型是什么,因为变量this是已知类型的列表。
2 回答
慕虎7371278
TA贡献1802条经验 获得超4个赞
类型推断不会从泛型方法调用中推断出缺少的参数。相反,它要么推断所有参数,要么不推断任何参数。因此,您不能使用一种类型参数调用该方法,并期望编译器给出其余的参数。
在这种情况下,可以推断TItemType
,因为它位于参数之一中。TListType
但无法推断,因为它是返回类型。因此最终无法推断方法签名,并且您必须指定所有类型参数。
Cats萌萌
TA贡献1805条经验 获得超9个赞
正如其他人所说,C# 不支持部分泛型类型参数推断。
关于为什么无法推断其中一种类型,也许一个更明显的例子可以更清楚地说明这一点:
TPeeledFruit peeled = Peel<TPeeledFruit, TFruit)( this TFruit fruit) where TPeeledFruit: TFruit
好吧,现在你说:
var myPeeledBanana = Peel(myBanana)
编译器很容易推断出一定TFruit
是Banana
。
但它如何推断出实际情况呢TPeeledFruit
?它没有任何此类信息;您可能会认为这是显而易见的,因为您了解其中的关系,但编译器没有这样的知识。它唯一知道的是,它TPeeledFruit
必须是一个继承自的类型TFruit
,但可以是无限数量的类型:它可以Banana
再次,它可以是PeeledBanana
,它可以是PeeledRipeBanana
,PeeledGreenBanana
等等。
还要考虑这样一个事实:显式键入赋值没有任何帮助:
PeeledBanana myPeeledBanana = Peel(myBanana)
这也行不通,C# 首先推理赋值右侧的类型,然后计算赋值是否实际上合法。如果它是隐式类型变量,则赋值始终有效。
- 2 回答
- 0 关注
- 112 浏览
添加回答
举报
0/150
提交
取消