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

假设我有一个 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是已知类型的列表。


倚天杖
浏览 77回答 2
2回答

慕虎7371278

类型推断不会从泛型方法调用中推断出缺少的参数。相反,它要么推断所有参数,要么不推断任何参数。因此,您不能使用一种类型参数调用该方法,并期望编译器给出其余的参数。在这种情况下,可以推断TItemType,因为它位于参数之一中。TListType但无法推断,因为它是返回类型。因此最终无法推断方法签名,并且您必须指定所有类型参数。

Cats萌萌

正如其他人所说,C# 不支持部分泛型类型参数推断。关于为什么无法推断其中一种类型,也许一个更明显的例子可以更清楚地说明这一点:TPeeledFruit&nbsp;peeled&nbsp;=&nbsp;Peel<TPeeledFruit,&nbsp;TFruit)( &nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;TFruit&nbsp;fruit)&nbsp;where&nbsp;TPeeledFruit:&nbsp;TFruit好吧,现在你说:var&nbsp;myPeeledBanana&nbsp;=&nbsp;Peel(myBanana)编译器很容易推断出一定TFruit是Banana。但它如何推断出实际情况呢TPeeledFruit?它没有任何此类信息;您可能会认为这是显而易见的,因为您了解其中的关系,但编译器没有这样的知识。它唯一知道的是,它TPeeledFruit必须是一个继承自的类型TFruit,但可以是无限数量的类型:它可以Banana再次,它可以是PeeledBanana,它可以是PeeledRipeBanana,PeeledGreenBanana等等。还要考虑这样一个事实:显式键入赋值没有任何帮助:PeeledBanana&nbsp;myPeeledBanana&nbsp;=&nbsp;Peel(myBanana)这也行不通,C# 首先推理赋值右侧的类型,然后计算赋值是否实际上合法。如果它是隐式类型变量,则赋值始终有效。
打开App,查看更多内容
随时随地看视频慕课网APP