假設我有一個 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 關注
- 156 瀏覽
添加回答
舉報
0/150
提交
取消