2

我正在编写具有封装对象的超类的代码,该对象特定于每个特定的子类,例如下面是子类类型与其封装的类类型的示例关系。所有封装类也对它们封装的类进行隐式强制转换。(非抽象的)。

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.AItemextends 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 来更新更改和管理插入/删除,而无需重新发明轮子。我正在使用部分类来执行此操作,但是与属于不同数据上下文的对象有太多混淆。

编辑:全文

我有一个由不同类型的调查对象组成的调查评估。一些调查对象,例如实际问题对象,是由不同的其他对象组成的。例如,块是具有项目库的调查对象,项目库由许多不同类型的项目组成(当前表示为子类)。到目前为止,我一直将 Linq to SQL 实体直接用作我的模型,并通过部分类进行了一些更改。项目有一个脚本,在调查中调用项目之前和之后执行。该脚本可以更改项目的某些属性,但由于我的 linq 类是我的模型,每当我通过 linq 的性质对它们进行更改时,它希望将这些更改持久化到数据库中。

有没有人看到更好的做事方式?

4

1 回答 1

2

请参阅有关协变和逆变的内容。您也许可以制作一个interface IEntity<out T> where T : class { T DataObject { get; } },并让您的抽象类实现它,然后您可以隐式地进行这种转换:

IEntity<Model.AItem> a = //something
IEntity<Model.Item> b = a; //it works!

如果你不能使用协变接口做到这一点,那么你就不能真正合乎逻辑地做你想做的事情,你应该尝试从其他角度找出解决方案。

于 2012-08-06T19:35:39.330 回答