Практическое применение object slicing C#(Присваивание объекта производного класса переменной базового класса)

На протяжении месяца мучаюсь вопросом о присвоении ссылке базового класса ссылку на класс наследника. К примеру

class Person
{
   public string Name;
}
class Worker:Person
{
   public void Work()
   {
       Console.WriteLine("Мало денег,надо работать")
   }
}

Можно объявить объект класса Person и присвоить ему объект класса Worker.

Person Nikita= new Worker();

Функционал у нашего Никиты будет обрезан, и из этого исходит вопрос, для чего это может пригодиться на практике, если мы могли присвоить Никите сразу класс Person и по идее получили бы тоже самое?


Ответы (2 шт):

Автор решения: eccs0103

Самый простой случай

...это когда у вас есть множество классов наследовавшие от Person и все они разные. Но они все ещё Person и нужно узнать имя каждого:

class Person
{
    public string Name;
}

class Worker: Person
{
    public void Work()
    {
        Console.WriteLine("Мало денег,надо работать");
    }
}

class Student: Person
{
    public void Teach()
    {
        Console.WriteLine("Мало знаний,надо учиться");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person Nikita = new Worker();
        Person Vasya = new Student();
        Person[] people = [Nikita, Vasya];
        foreach (Person person in people)
        {
            Console.WriteLine(person.Name);
        }
    }
}

Почему по другому нельзя?

К примеру, если мы создадим экземпляр Person потом мы не сможем использовать его как Worker:

class Program
{
    static void Main(string[] args)
    {
        Person Nikita = new Person();
        Worker NikitaAsWorker = (Worker) Nikita; // Вот эта конвертация приведет к ошибке
        NikitaAsWorker.Work();
    }
}

А вот так можно:

class Program
{
    static void Main(string[] args)
    {
        Person Nikita = new Worker();
        Worker NikitaAsWorker = (Worker) Nikita;
        NikitaAsWorker.Work();
    }
}
→ Ссылка
Автор решения: Dev18

Присвоение объекта производнго класса переменной базового класса — это ключевая возможность, которую предоставляет полиморфизм в C#. Когда вы создаете переменную базового класса и присваиваете ей объект производного класса, вы получаете возможность рабтать с объектами через общий интерфейс базвого класса

Это особенно полезно, когда нужно обрабатывать коллекцию различных объектов, у которых есть общие свойства, но разные реализации методов.

Person Nikita = new Worker { Name = "Nikita" };
Person Vasya = new Student { Name = "Vasya" };
Person[] people = { Nikita, Vasya };

foreach (Person person in people)
{
    Console.WriteLine(person.Name);
}

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

Worker worker = Nikita as Worker;
worker?.Work();

Таким образом, функционал не теряется, а управление становится гибче.

В случае с object slicing в C++ происходит копирование только базвой части объекта, тогда как в C# это не актуально, так как переменные класса хранят ссылки на объекты. Поэтому вам не нужно беспокоиться о том, что функционал будет "обрезан"

→ Ссылка