Как отличить базовый класс от его предка?

public class Shape { }
public class Circle : Shape { }

class Program
{
        static void Main(string[] args)
        {
            Circle circle = new Circle();
            Console.WriteLine(circle.GetType().Name);
            Shape shape = circle;
            Console.WriteLine(shape.GetType().Name); // - Можно ли как то получить исходный тип shape? 
            Circle circle2 = (Circle)shape;
            Console.WriteLine(circle2.GetType().Name);
        }
}

Результат:
Circle
Circle
Circle

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

Автор решения: Exploding Kitten

Можно:

void GetType<T>(T t) => Console.WriteLine(typeof(T));

Это работает т.к. на этапе компиляции будут определяться типы (а не в рантайме), на основании типа переменной, а не фактического объекта, который хранится в ней. Т.е.:

Shape shape = circle;
GetType(shape);
Circle circle2 = (Circle)shape;
GetType(circle2);

IL превратится в:

call void Program::GetType<class Shape>(!!0)
call void Program::GetType<class Circle>(!!0)

а уже рантам JIT-ом создаст два метода для каждого из типов, в которых и будет определяться он правильно.

→ Ссылка