Does compile-time type still exist at runtime? [closed]

Solution for Does compile-time type still exist at runtime? [closed]
is Given Below:

Let Dog be a class inherited from Animal class, we can do the instantiation as follows:

Animal a = new Dog();

I know that at compile time, the compiler only knows that we are declaring a as an Animal, and when it’s at runtime, we are pointing a to a Dog object. But there is something vague to me at this point:

Is the compile-time type Animal being the type of the variable a on the stack? Or is it just an information telling the compiler at compile time what type of object may be referenced by a and has nothing to do with the type of the variable a on the stack?


I am asking this because I’m wondering if the information on the compile-time type Animal still exists at runtime or if it will become completely irrelevant and is discarded? If it still exists, is it stored as the type of the variable a on the stack? And if so, when we are referring to the type of a, how does the program know if we are referring to the type of the object referenced by a or the type of the variable a on the stack?

I’m new to this concept and may have some misunderstandings. Could anyone please clarify for me? Thanks in advance!

Is the compile-time type Animal being the type of the variable a on the stack?

Yes (although saying on the stack is unnecessary – whether it is on the stack or not is irrelevant).

Check the IL for the code at SharpLab:

using System;
using System.Reflection;

public class Animal{}

public class Dog: Animal {}

public class Program
{
    
    public static void Main()
    {
        Animal a = new Dog();

        ShowType(a);
        
        MethodInfo mi = typeof(Program).GetMethod("Main");
        MethodBody mb = mi.GetMethodBody();

        foreach (LocalVariableInfo lvi in mb.LocalVariables)
        {
            Console.WriteLine("Local variable: {0}", lvi.LocalType);
        }
    }
    
    public static void ShowType<T>(T o)
    {
        Console.WriteLine(typeof(T)); // Animal
        Console.WriteLine(o.GetType()); // Dog
    }
}

Note, in particular:

.locals init (
    [0] class Animal a
)

which clearly shows that the type of the variable is Animal (which is no surprise, it will always be consistent with the code).

Note also that reflection (at runtime) outputs Animal (not Dog). So clearly the metadata of the method is storing the variable type.

TLDR: yes, the compile-time Animal type metadata exists in it’s entirety when ever that assembly is brought in to the runtime. Try to avoid using Reflection in your app if possible, but if you truly need it, tread lightly.

.NET has a robust type system to support dynamic run-time linking (which is why class library project types compile down to DLLs). If a developer expresses anything against the type system, it should be captured within the Assembly.

During compilation, the compiler takes the stance that it shouldn’t assume how that type could be used by other Assemblies’ types are used during runtime (even if they are marked as private – check out System.Reflection).

IMHO, Reflection is one of those guilty pleasures that C#/.NET (and VB.NET) took from classic VB days and Java metadata systems… there’s a lot of power in being able to “dynamically” work within a static type system, but there’s lots of overhead and issues that can/should be avoided it at all possible.