我遇到了这样一种情况,在父/子层次结构中,我有两层多态性,一层在另一层中。
我认为最好用一个简单的例子来解释:
class Group
{
public IList<Person> People { get; set; }
}
class SpecialGroup : Group
{
public IList<SpecialPerson> People { get; set; }
}
class Person {}
class SpecialPerson : Person {}
所以一个Group有一个Person对象的列表,而一个专门的Group(SpecialGroup)有一个专门的Person(SpecialPerson)对象的列表。
这可以编译,但我收到一条警告,说我应该在 SpecialGroup.People 上使用“new”关键字,因为它隐藏了 Group.People 属性。
我理解这意味着什么,但也许我不完全理解您如何在 C# 中正确地建模这样的东西。关于如何以更好的方式对此建模有任何想法吗?
此外,知道这将如何与 NHibernate 一起使用吗?我不确定使用“new”关键字是否会减少它,因为 Group.People 属性已经映射到不同的类型。有没有更好的方法来建模,以与 NH 兼容的方式?
好吧,我想到了一种使用泛型对其进行建模的方法:
abstract class AbstractGroup<PersonType>
where PersonType : Person
{
public IList<PersonType> People { get; set; }
}
class Group : AbstractGroup<Person>
{}
class SpecialGroup : AbstractGroup<SpecialPerson>
{}
class Person {}
class SpecialPerson : Person {}
我认为这符合我的要求?现在 Person 可以与 SpecialPerson 共享特征,但只能将 SpecialPerson 添加到 SpecialGroup。 AbstractGroup 基本类型可以对任何组的共同特征进行建模。
现在的问题是,如果我尝试映射它,NH 会爆炸吗?
郑重声明,似乎有些人已经成功地使用泛型类的查询 - 对于 HQL 查询(我的用例),这是不受支持的。
我想到的另一种方法是简单地隐藏父属性的实现,例如对子类中的覆盖属性使用“new”关键字 - 以下线程讨论了为什么它也不起作用:
NHibernate: Table Per Subclass Mapping and the New Keyword
到目前为止的结论:运行时检查和异常,正如下面@empi 所建议的。
最佳答案
这种情况也称为“平行”或“双重”继承。
通常在一个层次结构中有一个特定的类,它与另一个层次结构相关。
虽然不是必需的,但每个类都有一个“通用”或“抽象”类更好,它必须被覆盖,但是,已经有了依赖的概念。
这种情况在图形界面控件中非常有用,但是, 可能适用于其他场景。
在这种特殊情况下,通常只显示第一级会更好:
............................................................
....+----------------+................+----------------+....
....| <<Abstract>> |..<<contains>>..| <<Abstract>> |....
....| AbstractGroup +<>--------------+ AbstractPerson |....
....| |................| |....
....+----------------+................+----------------+....
............................................................
尽管如此,您可以对多个级别进行建模,但不推荐:
............................................................
....+----------------+................+----------------+....
....| <<Abstract>> |..<<contains>>..| <<Abstract>> |....
....| AbstractGroup +<>--------------+ AbstractPerson |....
....| |................| |....
....+-------+--------+................+--------+-------+....
............|..................................|............
............|..................................|............
............^..................................^............
............|..................................|............
............|..................................|............
....+-------+--------+................+--------+-------+....
....| <<Concrete>> |..<<contains>>..| <<Concrete>> |....
....| Group +<>--------------+ Person |....
....| |................| |....
....+----------------+................+----------------+....
............|..................................|............
............|..................................|............
............^..................................^............
............|..................................|............
............|..................................|............
....+-------+--------+................+--------+-------+....
....| <<Concrete>> |..<<contains>>..| <<Concrete>> |....
....| SchoolGroup +<>--------------+ Student |....
....| |................| |....
....+----------------+................+----------------+....
............................................................
您提到 NHibernate,您的类是否表示要存储的数据?
一些类似的问题:
Avoiding parallel inheritance hierarchies
Parallel Inheritance Hierarchy Refactoring
How to avoid parallel inheritance hierarchies among GUI controls and domain objects
Parallel Inheritance between Interface Classes and Implementation Classes in C++
干杯。
关于c# - 建模(和映射)具有两个多态性的类层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9436605/