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
,