[英]Why doesn't type inference work in this situation?
假設我有一個POCO和一個List類:
class MyClass
{...}
class MyClasses : List<MyClass>
{...}
以及將IEnumerable<MyClass>
映射到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'的定義,並且沒有可訪問的擴展方法'ToListOfType'可以找到類型'IEnumerable'的第一個參數(您是否缺少using指令或程序集引用?)
但是,這確實有效:
var list = someListOfMyClass.ToListOfType<MyClasses, MyClass>();
我不明白為什么類型推斷不足以讓編譯器知道項類型是什么,因為this
變量是一個已知類型的列表。
類型推斷不會從泛型方法調用中推斷缺少的參數。 相反,它要么推斷所有參數,要么都不推論。 因此,您無法使用一個類型參數調用該方法,並期望編譯器提供其余的參數。
在這種情況下,可以推斷TItemType
,因為它位於其中一個參數中。 TListType
是返回類型,所以無法推斷TListType
。 所以最后,無法推斷方法簽名,您必須指定所有類型參數。
正如其他人所說,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#原因類型,然后如果作業實際上是合法的則可以解決。 如果它是隱式類型變量,則賦值始終有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.