Что такое UpCast и DownCast в C#

Приведение типов (casting) в C# позволяет преобразовывать объекты одного типа в другой. В этом контексте различают UpCast (приведение вверх) и DownCast (приведение вниз).

UpCast (приведение вверх)

UpCast — это преобразование объекта производного класса в базовый тип. Такое преобразование всегда безопасно и выполняется неявно.

Пример UpCast

using System;

class Animal
{
    public void Speak() => Console.WriteLine("Animal sound");
}

class Dog : Animal
{
    public void Bark() => Console.WriteLine("Woof");
}

class Program
{
    static void Main()
    {
        Dog dog = new Dog();
        Animal animal = dog; // UpCast (неявное приведение)
        animal.Speak(); // Animal sound
    }
}

В этом примере объект dog приводится к типу Animal. Это возможно, потому что Dog является наследником Animal.

DownCast (приведение вниз)

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

Пример DownCast

using System;

class Animal
{
    public void Speak() => Console.WriteLine("Animal sound");
}

class Dog : Animal
{
    public void Bark() => Console.WriteLine("Woof");
}
}

class Program
{
    static void Main()
    {
        Animal animal = new Dog(); // UpCast
        Dog dog = (Dog)animal; // DownCast (явное приведение)
        dog.Bark(); // Woof
    }
}

В этом примере объект animal, который на самом деле является Dog, приводится обратно к Dog, что позволяет вызвать метод Bark().

Использование is и as для безопасного DownCast

Так как DownCast может привести к исключению InvalidCastException, можно использовать операторы is и as для безопасного приведения.

Пример с is

Animal animal = new Dog();
if (animal is Dog dog)
{
    dog.Bark();
}

Пример с as

Animal animal = new Dog();
Dog dog = animal as Dog;
if (dog != null)
{
    dog.Bark();
}

Оператор is проверяет, совместим ли объект с типом, а as выполняет приведение, но возвращает null, если оно невозможно, избегая исключений.