С# Наследование и литье
У меня есть следующий код, я получаю следующее исключение: InvalidCastException: Невозможно применить объект типа "Сотрудник" к типу "EmployeeProfile".
private class Employee
{
public string Name { get; private set; }
public Employee()
{
this.Name = "employee";
}
public override string ToString()
{
return this.Name;
}
}
private class EmployeeProfile : Employee
{
public string Profile { get; private set; }
public EmployeeProfile() : base()
{
this.Profile = string.Format("{0} profile", this.Name);
}
public override string ToString()
{
return this.Profile;
}
}
public void RunTest()
{
Employee emp = new Employee();
EmployeeProfile prof = (EmployeeProfile)emp; // InvalidCastException here
System.Console.WriteLine(emp);
System.Console.WriteLine(prof);
}
Возможно, мой мозг сгорел, но я думал, что вы можете применить подтип к его базовому типу? Что мне здесь не хватает? Может быть, это отпуск... спасибо!
Ответы
Ответ 1
Вы можете применить подтип к базовому типу. Но вы бросаете экземпляр базового типа в подтип.
EmployeeProfile - это Сотрудник. Не обязательно наоборот.
Итак, это сработает:
EmployeeProfile prof = new EmployeeProfile();
Employee emp = prof;
Однако эта модель воняет плохим дизайном. Профиль сотрудника не является особым видом сотрудника, не так ли? Для сотрудника имеет смысл иметь профиль. Вы находитесь за рисунком композиции здесь.
Ответ 2
Все ответы правильны... просто предоставляя без излишеств простое объяснение...
class Employee
class Female : Employee
class Male: Employee
Просто потому, что вы Employee
не делает вас Female
...
Ответ 3
Возможно, мой мозг сгорел, но я подумал, что вы можете применить подтип к его базовый тип?
Вы пытаетесь применить базовый тип к своему подтипу. Точно противоположное тому, что вы говорите:
Employee emp = new Employee();
EmployeeProfile prof = emp;
Ответ 4
Вам понадобится метод в EmployeeProfile. taht принимает Employee в качестве аргумента и создает EmployeeProfile.
EmployeeProfile enrichEmployee(Employee emp)
{
EmployeeProfile empprof = new EmployeeProfile();
empprof.property1 = emp.property1;
empprof.property2 = emp.property2;
empprof.property3 = emp.property3;
return empprof;
}
Ответ 5
Вы идете в неправильном направлении. В вашем коде EmployeeProfile используется особый тип Employee, а не наоборот. Поэтому, когда вы пытаетесь применить обратное, компилятор говорит, что "Employee" не является производным от "EmployeeProfile"
Ответ 6
Вам нужно использовать библиотеку, например Automapper. Эта библиотека может заполнить согласованные свойства для объекта:
Mapper.Initialize(cfg => {
cfg.CreateMap<EmployeeProfile,Employee>();
});
EmployeeProfile prof = Mapper.Map<EmployeeProfile>(emp);