2

У меня есть базовый класс с абстрактными свойствами. Я хочу, чтобы все наследующие классы переопределяли абстрактные свойства. Пример:Наследование абстрактных классов с абстрактными свойствами

public class Person 
{ 
    public string Name{get;set;} 
    public string LastName{get;set;} 
} 

public class Employee : Person 
{ 
    public string WorkPhone{get;set;} 
} 

public abstract class MyBase 
{ 
    public abstract Person Someone {get;set;} 
} 

public class TestClass : MyBase 
{ 
    public override Employee Someone{get;set;} //this is not working 
} 

Базовый класс имеет свойство Кто-то с Person типа. Я переоцениваю Someone недвижимость на моем TestClass. Теперь я хочу использовать тип Employee вместо Person. Мой класс Employee наследует от Person. Я не мог заставить его работать. Что мне делать, чтобы избежать этой проблемы?

Помогите оценить!

+0

Вы никогда не реализуете 'Person Someone', а' Employee Someone' не находится в базовом классе ('MyBase'). – Matthew

+0

Возможный дубликат [C# covariant return types using generic] (http://stackoverflow.com/questions/4348760/c-sharp-covariant-return-types-utilizing-generics) – nawfal

ответ

1

Проблема в том, что вы можете назначить сотрудника для экземпляра Person, но вы также не можете назначить экземпляр Person to Employee. Поэтому ваш сеттер сломается. Вы либо должны избавиться от сеттера, или использовать частный случай подложки и некоторые отливки (которые я бы не рекомендовал), который будет выглядеть так:

public class TestClass : MyBase 
{ 
    private Employee _employee; 

    public Person Someone 
    { 
     get 
     { 
      return _employee; 
     } 
     set 
     { 
      if(!(value is Employee)) throw new ArgumentException(); 
      _employee = value as Employee; 
     } 
} 
+0

Спасибо за объяснение! – Dilshod

+0

Я также использовал этот подход, но мне это не нравится. Учитывая, что я не могу отказаться от сеттера, что вы тогда рекомендуете? Или OP, и я неправильно использую этот шаблон? – propagated

0

Это форма возврата типа ковариации, который не разрешено в C#, к сожалению.

См. Ответ Эрика Липперта here.

1

Вы можете использовать Generics если вы хотите производные классы использовать Этие Employee или Person

Что-то вроде:

public class Person 
{ 
    public string Name { get; set; } 
    public string LastName { get; set; } 
} 

public class Employee : Person 
{ 
    public string WorkPhone { get; set; } 
} 

public abstract class MyBase<T> where T : Person 
{ 
    public abstract T Someone { get; set; } 
} 

public class TestClass : MyBase<Employee> 
{ 
    public override Employee Someone { get; set; } 
} 

public class TestClass2 : MyBase<Person> 
{ 
    public override Person Someone { get; set; } 
} 
0

Короче говоря: каждый Employee объекта является Person объектом. Но не каждый объект Person является объектом Employee.

Вот почему компилятор жалуется, потому что вы хотите, чтобы лечить Employee объект как Person объекта в каком-то месте что Person явно требуется - что может быть любой объект, полученный от лица включаяEmployee; не конкретноEmployee.

Примечание: @ sa_ddam213 предоставил решение в своем ответе, если вам действительно нужно сделать это явно.

Смежные вопросы