2013-05-01 81 views
2

C#4.0 .NET 4.5 Silverlight 5 看起來很奇怪,我不能找到解決方案,所以需要一些幫助。C#泛型類中的協變性

我有基類Base和派生類Child:Base。我也有助手類具有泛型類型來做具體的工作一個EF實體助手,其中T:EntityObject。

子對特定的實體MyEntity:EntityObject做特定的工作。

所以,我想:

public class Base 
{ 
    protected Helper<EntityObject> helper; 
} 
public class Child : Base 
{ 
    public Child() 
    { 
     helper = new Helper<MyEntity>(); 
    } 
} 

我希望有更多的派生類必須瞭解更具體的泛型參數,我認爲這就是協方差......但是,這並不工作...

設計這樣的課程的「正確」方式是什麼?

編輯:對不起,我沒能100%清楚爲什麼不能我實現我需要什麼。

a。通用基地的解決方案不起作用,因爲基地的用戶不知道T型。試想一下:

public class User 
{ 
    private Base<T> base; // this will not compile. 
    public User(TypeEnum t) 
    { 
     if(t == TypeEnum.MyEntity) base = new Child(); 
... 

灣帶接口的解決方案不起作用,因爲幫助器在任何地方都使用T(它的目的是否正確?)。想象一下,它有方法

public IEnumerable<T> Process(IEnumerable<T> items) { return items; } 

我如何把它的界面,不知道大約T t

+1

你看到了什麼錯誤? 「不起作用」是什麼意思? – 2013-05-01 11:50:28

+2

'助手「是什麼樣的? 'MyEntity'和'EntityObject'之間的關係是什麼? – 2013-05-01 11:52:28

+1

幫手類是這裏最重要的部分 – NSGaga 2013-05-01 11:54:53

回答

4

如果FooBar,這並不意味着Some<Foo>Some<Bar>。有兩種方法可以做你想做的事。第一種方法是使基型通用,使得:

Base<T> where T : EntityObject { 
    protected Helper<T> helper; 
} 
Child : Base<MyEntity> {...} 

第二個是在基礎類型使用一個非通用的接口,即,具有

Base { 
    protected IHelper helper; 
} 
Child : Base {...} 

其中在後一種情況下,Helper<T> : IHelper,對於一些非通用的IHelper待定義。

作爲一個附註,您可能會可能找到更容易在構造函數中傳遞值而不是使用protected字段。

+0

Marc。這些解決方案都不可用。因爲如果Base 那麼Child的用戶不知道T(否則爲什麼我需要泛型)。在接口的情況下 - 你不能在IHelper中聲明使用T的方法,並且幫助者在每個地方都使用它(這是它的目的)....我使用explantaions更新了我的問題..但是我相信你自己可以看到它...有沒有辦法呢? – 2013-05-01 12:19:16

+0

@BoppityBop的確是這些限制;泛型不是一種魔術棒,它可以使代碼執行與通常所能做的不同的事情 – 2013-05-01 13:32:49

5

我認爲這是什麼,你在做什麼後:

public class Base<T> where T : EntityObject 
{ 
    protected Helper<T> helper; 
} 
public class Child : Base<MyEntity> 
{ 
    public Child() 
    { 
     helper = new Helper<MyEntity>(); 
    } 
} 

編輯(響應您的編輯):您可以添加一個Base,使用像這樣:

public class Base 
{ 
    // put anything here that doesn't rely on the type of T 
    // if you need things here that would rely on T, use EntityObject and have 
    // your subclasses provide new implementations using the more specific type 
} 
public class Base<T> : Base where T : EntityObject 
{ 
    protected Helper<T> helper; 
} 
public class Child : Base<MyEntity> 
{ 
    public Child() 
    { 
     helper = new Helper<MyEntity>(); 
    } 
} 
public class User 
{ 
    private Base myBase; 
    public User(TypeEnum t) 
    { 
     if(t == TypeEnum.MyEntity) myBase = new Child(); 
     ... 
+0

請參閱編輯。謝謝 – 2013-05-01 12:21:53

+0

@BoppityBop更新了我的答案;這是否符合你的需求?如果沒有,我無法理解您想如何使用它。如果你可以解釋一下,也許它會更有意義:你需要什麼樣的多態性,你需要什麼公共成員在'Base'上,等等。 – 2013-05-01 15:01:21

+0

Tim,**將會是一個確實的解決方案......但是有一個小問題 - 這不會編譯...泛型參數必須存在... ...真是令人失望..我認爲這是泛型的自然使用..但顯然(根據大師)這是魔術......好吧......我無話可說。 – 2013-05-01 15:42:02