我正在编写具有超类的代码,该代码封装了特定于每个特定子类的对象,例如下面是具有其封装类的类的子类类型的示例关系。所有封装类也对它们封装的类进行隐式转换。 (非抽象的)。
Item => Model.Item
Box => Model.Box
我没有使用非类型安全object
类型,而是觉得我可以使用泛型来获得类型安全和优雅。
public abstract class Entity<T> where T: class
{
protected T DataObject;
}
public class Item : Entity<Model.Item>
{
// Can use this.DataObject and it is type Model.Item
}
public class Box : Entity<Model.Box>
{
// Can use this.DataObject and it is type Model.Box
}
这种方法运行正常,直到我想开始制作二级子类,所以我将Item
的定义更改为(注意Model.AItem
extends Model.Item
)
public class Item<T> : Entity<T> where T : Model.Item
{
// Can use this.DataObject and it is type Model.Item
}
public class AItem : Item<Model.AItem>
{
// Can use this.DataObject and it is type Model.AItem
}
这对我来说有两个主要问题,一个是当我想引用一个二级对象作为我必须放入的抽象类时Item<Model.Item>
我希望有一种方法可以隐含在那里绝不是一个不真实的情况。此外,由于无法实例化,它会对我使用抽象类的隐式转换造成严重破坏。
没有什么不起作用,我基本上想要删除遗传参数,同时仍然保持具有特定类型的封装对象的能力。封装对象实际上是一个Linq to SQL对象,周围的对象正在形成一种缓冲,用于更改以及实现其他功能,并提供更直接的数据表示,就像在应用程序中一样。我需要保留LinqToSql实体,这样我仍然可以使用LinqToSql更新更改并管理插入/删除而无需重新发明轮子。我使用部分类来执行此操作,但是对于属于不同datacontexts的对象有太多混淆。
编辑:全文
我有一个由不同类型的调查对象组成的调查评估。某些调查对象(例如实际问题对象)由不同的其他对象组成。例如,块是具有迭代库的调查对象,项目库由可以是许多不同类型的项目组成(当前表示为子类)。到目前为止,我一直在使用Linq to SQL enties作为我的模型,并通过部分类进行了一些更改。项目有一个脚本,在调查中调用项目之前和之后执行。这个脚本可以改变项目的某些属性,但由于我的linq类是我的模型,每当我根据linq的性质对它们进行更改时,它希望将这些更改保存到数据库中。
有没有人看到更好的办法?
答案 0 :(得分:2)
见this about covariance and contravariance。您可以创建interface IEntity<out T> where T : class { T DataObject { get; } }
,并使您的抽象类实现此功能,然后您可以隐式执行此类转换:
IEntity<Model.AItem> a = //something
IEntity<Model.Item> b = a; //it works!
如果你不能使用协变界面做到这一点,那么你无法在逻辑上做你想做的事情,你应该尝试从其他角度找出解决方案。