While modelling my domain classes, I found that Entity Framework lets you model inheritance relationships, but doesn't support promoting a base type instance to its derived type, i.e. changing an existing Person row in the database to an Employee, which derives from Person.
Apparently, I wasn't the first to wonder about this, because this question has been asked and answered on Stack Overflow multiple times (e.g. see here and here).
As indicated in these answers, Entity Framework doesn't support this because this isn't allowed in Object-Oriented Programming either: once an instance is created, you cannot change its run-time type.
Fair enough, from a technical perspective I can understand that once a single block of memory is allocated for an object, tacking on a few extra bytes afterwards to hold the derived type's fields in will probably require the entire memory block to be reallocated, and as a consequence, will mean that the object's pointer has now changed, which in turn introduces even more problems. So I get that this would be difficult to implement, and therefore not supported in C#.
However, aside from the technical component, the answers (and here too, see final paragraph on page 1) also seem to imply that it is considered bad design when you want to change an objects run-time type, saying that you shouldn't need this kind of type-changing and should use composition for these situations instead.
Frankly, I don't get why - I'd say its perfectly valid to want to work Employee instances in the same way as you would with a Person instance (i.e. by inheriting Employee from Person), even if at some point in time a Person will be hired as an Employee, or an Employee quits and becomes a Person again.
Conceptually, I don't see anything wrong with this?
Can anyone explain this to me?
--Edit, to clarify, why is this considered bad design:
public class Person
{
public string Name { get; set; }
}
public class Employee: Person
{
public int EmployeeNr { get; set; }
public decimal Salary { get; set; }
}
...but this isn't?
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; }
}