C#generics类中的协方差
C#4.0 .NET 4.5 Silverlight 5我似乎无法找到解决方案,所以需要一些帮助。
我有基类Base和派生类Child:Base。 我还有一个helper类,它具有generics类型来执行特定的工作,一个EF实体Helper,其中T:EntityObject。
Child使用特定实体MyEntity:EntityObject执行特定工作。
所以我尝试过:
public class Base { protected Helper helper; } public class Child : Base { public Child() { helper = new Helper(); } }
我希望更多派生类必须知道更具体的generics参数,我认为这是什么协方差……但是这不起作用……
这样设计课程的“正确”方法是什么?
编辑:抱歉,我没有100%清楚为什么我无法实现我的需要。
一个。 使用通用Base的解决方案不起作用,因为Base的用户不知道T类型。 想像:
public class User { private Base base; // this will not compile. public User(TypeEnum t) { if(t == TypeEnum.MyEntity) base = new Child(); ...
湾 使用Interface的解决方案不起作用,因为帮助程序在任何地方使用T(它的目的是什么?)。 想象一下它有方法
public IEnumerable Process(IEnumerable items) { return items; }
如何在不知道任何关于T的界面中提起它
如果Foo
: Bar
,那并不意味着Some
: Some
。 有两种方法可以做你想要的。 第一种是使基类型通用,使得:
Base where T : EntityObject { protected Helper helper; } Child : Base {...}
第二种是在基类型上使用非generics接口,即具有
Base { protected IHelper helper; } Child : Base {...}
在后一种情况下, Helper
,对于某些非通用的IHelper
来定义。
作为旁注,您可能会发现在构造函数中传递值更容易,而不是使用protected
字段。
我想这就是你所追求的:
public class Base where T : EntityObject { protected Helper helper; } public class Child : Base { public Child() { helper = new Helper (); } }
编辑(响应您的编辑):您可以添加一个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 : Base where T : EntityObject { protected Helper helper; } public class Child : Base { public Child() { helper = new Helper (); } } public class User { private Base myBase; public User(TypeEnum t) { if(t == TypeEnum.MyEntity) myBase = new Child(); ...