2013-05-01 77 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