Я пытаюсь понять, как CLR реализует ссылочные типы и полиморфизм. Я сослался на Essential .Net Vol 1 Дона Бокса, который очень помогает восполнить большую часть материала. Но я застрял / смущен следующей проблемой, когда попытался поиграть с некоторым кодом IL, чтобы лучше понять.
Я постараюсь объяснить проблему как можно лучше. Рассмотрим следующий код
class Base
{
public void m()
{
Console.WriteLine("Base.m");
}
}
class Derived : Base
{
public void m()
{
Console.WriteLine("Derived.m");
}
}
. Теперь рассмотрим простое консольное приложение с IL основного метода, показанного ниже. Я вручную настроил IL, созданный компилятором, чтобы понять и снова собрать его с помощью ILAsm.exe
.class private auto ansi beforefieldinit Console1.Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 44 (0x2c)
.maxstack 1
.locals init ([0] class Console1.Base d)
nop
newobj instance void Console1.Base::.ctor()
stloc.0
ldloc.0
callvirt instance void Console1.Derived::m()
nop
call string [mscorlib]System.Console::ReadLine()
pop
ret
} // end of method Program::Main
} // end of class Console1.Program
. Я ожидал, что этот код НЕ запустится, поскольку ссылка на объект указывает на объект Base, и нет возможности таблица методов базового объекта будет иметь запись для метода m (), определенного в классе Derived.
Но волшебным образом этот код выполняет Derived.m () !!
Итак, есть два вопроса, которые я не задаю. Я понимаю в приведенном выше коде:
Какое значение имеет Тип, указанный в приведенном ниже коде IL? Я попытался поэкспериментировать, изменив это на разные типы (например, System.Exception !!), и никаких ошибок не сообщалось. Почему ??
.locals init ([0] класс Console1.Base d)
Заранее спасибо !!
С уважением, Ajay