为了账号安全,请及时绑定邮箱和手机立即绑定

为什么类型推断在这种情况下不起作用?

为什么类型推断在这种情况下不起作用?

C#
倚天杖 2023-09-24 11:09:44
假设我有一个 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但无法推断,因为它是返回类型。因此最终无法推断方法签名,并且您必须指定所有类型参数。


查看完整回答
反对 回复 2023-09-24
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

正如其他人所说,C# 不支持部分泛型类型参数推断。

关于为什么无法推断其中一种类型,也许一个更明显的例子可以更清楚地说明这一点:

TPeeledFruit peeled = Peel<TPeeledFruit, TFruit)(
    this TFruit fruit) where TPeeledFruit: TFruit

好吧,现在你说:

var myPeeledBanana = Peel(myBanana)

编译器很容易推断出一定TFruitBanana

但它如何推断出实际情况呢TPeeledFruit?它没有任何此类信息;您可能会认为这是显而易见的,因为您了解其中的关系,但编译器没有这样的知识。它唯一知道的是,它TPeeledFruit必须是一个继承自的类型TFruit,但可以是无限数量的类型:它可以Banana再次,它可以是PeeledBanana,它可以是PeeledRipeBananaPeeledGreenBanana等等。

还要考虑这样一个事实:显式键入赋值没有任何帮助:

PeeledBanana myPeeledBanana = Peel(myBanana)

这也行不通,C# 首先推理赋值右侧的类型,然后计算赋值是否实际上合法。如果它是隐式类型变量,则赋值始终有效。


查看完整回答
反对 回复 2023-09-24
  • 2 回答
  • 0 关注
  • 112 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信