.NET 4.x В чем разница между call и callvirt - C#
Формулировка задачи:
Вопрос касательно IL кода программы. Вычитал у Рихтера, что разница между командами Полученный il код файла и заменить
call
иcallvirt
при применении к невиртуальному методу состоит в том, чтоcallvirt
проверяет объект, функция которого вызывается и кидаетNullReferenceException
в случаеnull
. И, мол, поэтомуcallvirt
работает чуть медленнее своего собрата. При этом, что происходит в случаеcall null.Function
, осталось неизвестным. Посему, я решил немного отредактировать код после компиляции и посмотреть, что будет во втором случае. Итак, исходный С# код таков:public class Test
{
static void Main()
{
Object p = null;
p.GetType();
}
}Test.exe
: Немного модифицирую 5 команду (Test.Patched.exe
): Консольный вывод при этом совпадает для обоих exe: Аналогично вывод совпадает если поставить catch в коде:static void Main()
{
Object p = null;
try { p.GetType(); }
catch(NullReferenceException) { Console.WriteLine("Exception..."); }
}callvirt
наcall
. Оба выводят Exception: Вопрос состоит в том, почему оба выбрасываютNullReferenceException
. Или как ведет себяcall
при обращении кnull
. P.S. На stackoverflow во втором ответе такое же объяснение разницы между этими двумя командами.Решение задачи: «.NET 4.x В чем разница между call и callvirt»
textual
Листинг программы
class Test
{
int x;
public void Do()
{
try { x = 33; }
catch(NullReferenceException) { Console.WriteLine("NullReferenceException in \"x=33\""); }
}
static void Main()
{
((Test)null).Do();
}
}