2015-09-23 154 views
7

我有一個泛型類與提供特定類型的子類。你可以繼承一個泛型類與一個特定類型的類嗎?

public abstract class GenericBase<T> 
    where T:Interface1 
{ 
} 

我子類仿製藥與特定的實施方式中:

public class Customer: 
    GenericBase<Type1> 

Type1器具Interface1)。

我有了這個參考另一個抽象基類:

protected GenericBase<Interface1> genericInstance; 

最後,當我試圖將genericInstance分配給基類的一個實例,它給了我一個編譯器錯誤,他說,它「不能將客戶隱式轉換爲GenericBase <Interface1>」。

base.genericInstance = new Customer(); //Compiler error 

我不明白爲什麼如果CustomerGenericBase<Type1>一個亞型,並Type1實現Interface1我會得到這個錯誤。如果它是GenericBase<Type1>的子類,是不是Customer實際上是一種GenericBase<Interface1>

我假設我誤解了這裏的泛型,有沒有辦法允許這種行爲?

+0

不確定在C#中,但是這絕對不能在Java中工作。在Java中,'genericInstance'必須聲明爲'protected GenericBase <?擴展Interface1> genericInstance'(注意:我沒有試過它看它是否真的有效)。 – Powerlord

+1

[協方差和反變量](https://msdn.microsoft.com/en-us/library/ee207183) –

+0

經驗法則是泛型不是協變的,因爲您不能說出將要做什麼。我不能將一個'List '分配給'List ',因爲否則,我可以在'List '中添加一個'Dog',儘管它真的是一個'List ' – Powerlord

回答

9

在C#中,協變(將派生類型分配給基類型)不能應用於泛型類。因此,您需要應用專門標記爲協變的接口,在新的接口IGenericBase上使用out parameter modifier

protected IGenericBase<Interface1> genericInstance = new Customer(); 

public interface IGenericBase<out T> {} 

public abstract class GenericBase<T> : IGenericBase<T> 
    where T:Interface1 {} 

public interface Interface1 {} 

public class Type1 : Interface1 {} 

public class Customer: GenericBase<Type1> {} 
+2

我知道C#有一些類似於Java怪異的''和''語法的操作符,我只是不知道它們是''和''。 – Powerlord

+0

我無法使用協變接口,因爲我的類型在接口中既被用作返回值又被用作輸入參數。但至少現在我對協變性有所瞭解;我以前沒有處理過的事情。 – GendoIkari

4

C#沒有泛型類的協變性,這基本上意味着您不能將具有更多派生類型參數的值賦值給具有較少派生類型參數的變量。

儘管如此,只要滿足一些條件即參數類型僅用於協變位置,即作爲方法和屬性的返回類型,那麼這將與接口一起工作。

有關更多信息,請參閱this和其他位文檔。