2013-09-27 39 views
2

如果我有這樣的代碼:非通用類的實現是不能繼承

public interface IThing<T> where T : class 
{ 
    // ... 
} 

public class BaseThing<T> : IThing<T> where T : class 
{ 
    // ... 
} 

public class ThingA : BaseThing<string> 
{ 
    // ... 
} 

public class ThingB : BaseThing<Uri> 
{ 
    // ... 
} 

此代碼失敗:

List<IThing<object>> thingList = new List<IThing<object>>(); 

thingList.Add(new ThingA()); 
thingList.Add(new ThingB()); 

即使ThingA(間接)繼承自(應該是一個實例)IThing<T>。爲什麼?是ThingA/ThingB不是IThing<T>的實例嗎?

+2

閱讀協變和逆變。 (除了知道這些概念是相關的,我並不知道回答這個問題的足夠的了。) – zimdanen

+2

請注意,IThing 的所有「實例」,如IThing ,IThing ,IThing 都是兄弟姐妹 - 它們之間沒有繼承關係。與IThing 沒有任何繼承關係,這是完全不同的東西(也不同於IThing <>' - [open generic])(http://stackoverflow.com/questions/2173107/what-exactly-is -an-開放通用型中網))。 –

回答

7

這將要求您的界面是協變的。詳情請參閱Covariance and Contravariance in Generics

在這種情況下,您可以通過使用使這項工作:

// Add out here 
public interface IThing<out T> where T : class 
{ 
} 

注意,這樣做的界面上進行限制,你可以用它做什麼,但是,因爲它需要的類型T在該接口只能用作接口內的方法返回類型,而不能用作一種形式化的方法參數。

如果這不可行,另一種選擇是創建一個非通用IThing接口,並使IThing<T>實現IThing。您可以使用List<IThing>作爲您的收藏。

+0

是的,我有界面中使用'T'定義的屬性(如'List '),所以這不起作用。還有什麼我可以改變設計,這將使這項工作,或者我應該看看重新設計呢? – qJake

+3

@SpikeX你需要重新構建它一下。一種選擇是製作一個非通用的IThing接口,並使其實現。然後,您可以創建一個'List '並使用它... –

+0

創建非通用接口來補充通用接口的訣竅。代碼編譯,甚至更好,MEF也重新開始工作。謝謝! – qJake