2015-02-11 412 views
13

請看下面的例子:爲什麼我不能使用兩個泛型類型參數的協方差?

class Base {} 

class Derived : Base {} 

class Test1 
{ 
    private List<Derived> m_X; 

    public IEnumerable<Base> GetEnumerable() 
    { 
     return m_X; 
    } 
} 

這編譯就好了,因爲IEnumerable<T>T

但是,如果我做同樣的事情,但現在仿製藥:

class Test2<TBase, TDerived> where TDerived : TBase 
{ 
    private List<TDerived> m_X; 

    public IEnumerable<TBase> GetEnumerable() 
    { 
     return m_X; 
    } 
} 

我得到的編譯器錯誤

無法轉換表達式類型 「System.Collection.Generic.List」返回類型 'System.Collection.Generic.IEnumerable'

我在做什麼錯在這裏?

+0

我想應該有一個解釋,但是,使用'return m_X.Cast ();'將解決你的情況。 – AgentFire 2015-02-11 14:51:08

回答

13

事情是,在第一種情況下,Base被稱爲一類。在第二種情況下,類型參數T可以是類或結構(這是編譯器認爲的)。

通過指定T是一類解決的情況下,錯誤將消失:

class Test2<TBase, TDerived> where TDerived : class, TBase 
{ 
    private List<TDerived> m_X; 

    public IEnumerable<TBase> GetEnumerable() 
    { 
     return m_X; 
    } 
} 

因此,編譯器試圖向我們表明TDerived可能是一個結構(因爲你沒有指定class約束)和as wealready know,協方差和逆變不適用於結構

+0

請原諒我的無知,因爲我對C#還是比較陌生的(或者也許這是關於.NET的一些真正深奧的事情之一),但是'TDerived'來自'TBase'這一事實 - 這是一個類 - 排除關於「TDerived」本身是類還是結構的歧義?你能從一個類派生一個結構嗎? – 2015-02-11 14:57:15

+0

有趣!我嘗試了'TBase:class'的地方,但那沒有效果。 – 2015-02-11 14:58:42

+0

@ roryap在C#中,但不一定在CLR中。 'ValueType'是一個類,但所有的結構都來自它。 – 2015-02-11 14:59:15

相關問題