Что такое Upcast и Downcast в C#?

«Что такое Upcast и Downcast в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Upcast и Downcast — это операции приведения ссылочного типа к типу в его иерархии наследования.

Upcast (Восходящее приведение)

Приведение объекта от производного типа к базовому. Это безопасная и неявная операция, так как производный класс всегда является частным случаем базового.

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

Dog myDog = new Dog();
// UPCAST: Неявное приведение Dog к Animal. Всегда безопасно.
Animal myAnimal = myDog; // myAnimal ссылается на объект Dog, но "видит" только Animal
// myAnimal.Bark(); // ОШИБКА КОМПИЛЯЦИИ: тип Animal не содержит метода Bark

Downcast (Нисходящее приведение)

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

Animal someAnimal = new Dog(); // Upcast

// 1. Явное приведение (опасное) - может вызвать InvalidCastException
Dog dog1 = (Dog)someAnimal; // Успешно, т.к. someAnimal - это Dog
dog1.Bark(); // Работает

Animal catAnimal = new Cat();
// Dog dog2 = (Dog)catAnimal; // InvalidCastException во время выполнения!

// 2. Безопасное приведение с помощью оператора 'as'
Dog dog3 = someAnimal as Dog; // Успешно, dog3 ссылается на Dog
Dog dog4 = catAnimal as Dog;  // Неудача, dog4 = null
if (dog4 != null) { /* безопасная работа */ }

// 3. Безопасная проверка и приведение с помощью оператора 'is' (рекомендуется)
if (someAnimal is Dog safeDog) // Проверка + приведение в одной строке
{
    safeDog.Bark(); // Безопасная работа с safeDog типа Dog
}
Ключевые различия: Характеристика Upcast Downcast
Направление К базовому типу К производному типу
Безопасность Гарантированно безопасно Требует проверки
Явность Неявное Явное (кроме as)
Исключение Никогда InvalidCastException

Практический совет: Всегда предпочитайте безопасные способы downcast (is или as с проверкой на null), чтобы избежать исключений времени выполнения. Используйте явное приведение (Type), только если вы абсолютно уверены в типе объекта (например, после проверки is).