Ast*_*ain 9 c# oop inheritance entity-framework
在对域类进行建模时,我发现Entity Framework允许您对继承关系进行建模,但不支持将基类型实例提升为其派生类型,即将数据库中现有的Person行更改为派生自Person的Employee.
显然,我并不是第一个对此感到疑惑的人,因为这个问题已经多次在Stack Overflow上被提出并回答(例如,见此处和此处).
如这些答案中所示,实体框架不支持这一点,因为在面向对象编程中不允许这样做:创建实例后,您无法更改其运行时类型.
很公平,从技术角度来看,我可以理解,一旦为一个对象分配了一个单独的内存块,之后添加一些额外的字节来保存派生类型的字段可能需要重新分配整个内存块,并且结果,意味着对象的指针现在已经改变,这反过来又引入了更多的问题.所以我觉得这很难实现,因此在C#中不受支持.
但是,除了从技术组件,答案(和这里也看到第1页最后一段)也似乎暗示着它被认为是不好的设计,当你想改变一个对象的运行时类型,说你不应该需要这种类型改变,而应该使用组合来代替这些情况.
坦率地说,我不明白为什么 - 我说完全有效的想要以与使用Person实例相同的方式工作Employee实例(即通过从Person继承Employee),即使在某个时间点a人员将被雇用为员工,或者员工退出并再次成为人员.
从概念上讲,我没有看到任何错误?
任何人都可以向我解释这个吗?
- 编辑,澄清,为什么这被认为是糟糕的设计:
public class Person
{
public string Name { get; set; }
}
public class Employee: Person
{
public int EmployeeNr { get; set; }
public decimal Salary { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
......但这不是?
public class Person
{
public string Name { get; set; }
public EmployeeInfo EmployeeInfo { get; set; }
}
public class EmployeeInfo
{
public int EmployeeNr { get; set; }
public decimal Salary { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
坦率地说,我不明白为什么 - 我想说,想要以与 Person 实例相同的方式工作 Employee 实例(即通过从 Person 继承 Employee)是完全有效的,即使在某个时间点人员将被雇用为雇员,或者雇员退出并再次成为人员。从概念上讲,我不认为这有什么问题吗?
我将其理解为Person -> Employee -> Person?也就是说,它仍然是一个人,但他/她/它被归因于“就业”,然后“降级”为只是一个人?
object当 类型在运行时不改变类型时,继承非常有用,例如,当您创建一个equity对象时,您可以非常确定您不想将其转换为 对象FRA,即使两者都是证券的子类。但是,每当运行时期间可能发生变化(例如行为)时,请尝试使用组合。在我之前的示例中,安全子类可能继承自顶级资产类,但用于为资产赋予市场价值的方法应该通过行为模式(例如策略模式)放置在那里,因为您可能想要在一个运行时使用不同的方法。
对于您所描述的情况,您不应使用继承。只要有可能,总是倾向于组合而不是继承。如果在运行时发生了某些变化,那么绝对不应该通过继承将其放在那里!
你可以把它比作生命,一个人出生时是一个人,死时也是一个人,一只猫出生时是一只猫,死时也是一只猫,某种类型的对象应该作为一种类型创建,垃圾收集时也应该作为同一类型。不要通过行为组合来改变某物是什么,而是改变它的行为方式或它所知道的内容。
我建议您看一下《设计模式:可重用面向对象软件的元素》,其中非常全面地涵盖了一些非常有用的设计模式。