C# List<T> добавление унаследованных элементов

Допустим, у нас есть 2 класса. Первый человек

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace People
{
    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

Второй учитель

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace People
{
    class Teacher:Person
    {
        public string Position { get; set; }
    }
}

И я хочу добавить в список учителя

Teacher teacher = new Teacher() {FirstName="Peter", LastName="Janson",Position="boss" };
            List <Person> people= new List<Person> { };
            people.Add(teacher);

Как это возможно, что я добавляю учителя в список, когда этот список имеет тип, и у человека есть только свойства FirstName и LastName, а у "учителя" также есть свойство Position?

2 ответа

Исходя из вашего предыдущего вопроса, я думаю, у вас есть некоторые проблемы с пониманием полиморфизма.

Попробуйте представить наследство как отношения между автомобилями и транспортными средствами. Транспортное средство - это базовый тип, а автомобиль, мотоцикл, самолет, грузовик и т. Д. - производный тип.

public class Vehicle
{
    public string Model {get;set;}
}

Представьте, что у вас есть самолетный ангар:

List<Vehicle> hangar = new List<Vehicle>();

Вы можете оставить несколько разных транспортных средств в ангаре самолета, потому что он очень большой:

hangar.Add(new Plane());
hangar.Add(new Car());

Хотя они разных типов, они все еще наследуются от транспортного средства, поэтому их можно хранить как транспортные средства.

Дело в том, что у самолетов есть крылья, а у машин нет. Если вы просто берете первый автомобиль hangar[0]вы знаете, что это автомобиль, и вы можете получить основную информацию о нем (информацию, которая является общей для всех транспортных средств): hangar[0].Model, но вы должны быть более точными в отношении типа транспортного средства, к которому вы обращаетесь, если вам нужна более подробная информация.

Теперь, так как вы можете не знать, что это за автомобиль, вам нужно проверить:

if (hangar[0] is Car)
{
    string registrationNumber = ((Car)hangar[0]).RegistrationNumber;
}
else if (hangar[0] is Plane)
{
    int numberOfWings = ((Plane)hangar[0]).NumberOfWings;
}

Используя синтаксис C#7, вы также можете использовать эту упрощенную форму:

if (hangar[0] is Car car)
{
    string registrationNumber = car.RegistrationNumber;
}
else if (hangar[0] is Plane plane)
{
    int numberOfWings = plane.NumberOfWings;
}

Аналогия с реальной жизнью заключается в том, что если вы войдете в ангар, вам придется посмотреть, где находится машина и где находится самолет. Здесь то же самое.

Полиморфизм позволяет вам рассматривать многие производные классы как их общую основу. В вашем личном примере это было бы полезно, если вы хотите иметь возможность искать кого-то по имени. Учитель - это человек, доктор - это человек, все они люди и у всех есть имена, так что в этой ситуации вы можете обращаться с ними одинаково.

Думайте об этом как о быстром знакомстве - вы идете и встречаете людей. Что ты делаешь первым? Вы спрашиваете имя другого человека. Затем вы спрашиваете: "Чем вы зарабатываете на жизнь?" и они говорят "я учитель" или "я врач". Теперь вы знаете, какого они типа, и вы можете спросить их: "Чему вы учите?" или "В какой отрасли медицины ты специализируешься?"

Надеюсь, это прояснит для вас:-)

Это вопрос о фундаментальной объектно-ориентированной концепции, называемой полиморфизмом. Teacher это Person, но твой список Person только экземпляры знают, что он содержит список Person экземпляры; он ничего не знает о классах, которые происходят от Person и не нужно.

Если вы работаете с элементами в своем списке, вы можете определить их тип, а затем преобразовать их в этот тип следующим образом:

foreach (Person x in people)
{
    if (x is Teacher)
    {
        Teacher y = (Teacher) x;
    }
}

Тогда вы можете получить доступ к свойствам учителя: y.Position,

Другие вопросы по тегам