簡體   English   中英

為什么在這種情況下不進行類型推斷?

[英]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 ,它可以是PeeledRipeBananaPeeledGreenBanana等。

還要考慮明確鍵入賦值的事實絕不會有任何幫助:

PeeledBanana myPeeledBanana = Peel(myBanana)

這也不會起作用,首先是在作業右側的c#原因類型,然后如果作業實際上是合法的則可以解決。 如果它是隱式類型變量,則賦值始終有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM