Pull to refresh

Интересный вопрос. Что выведет данная программа? А скомпилируется ли она вообще?

var str = new TheBestStructEver(5);

Console.WriteLine(str.A);

public struct TheBestStructEver
{
    public int A;

    public TheBestStructEver(int a)
    {
        A = a;
        this = new TheBestStructEver();
    }
}

Ответ: Да, скомпилируется, причем без всяких предупреждений, и выведет 0.

Давайте разберем почему это так. Обратимся к IL-коду нашей структуры, а конкретнее к 12-ой строчке. Вот как она выглядит в IL-коде:

IL_0013: ldarg.0
IL_0014: initobj      TheBestStructEver

Итак, первая строчка загружает в стек нулевой аргумент, переданный в метод (конструктор - тоже метод). Аргумент под нулевым индексом - это указатель на объект, в котором мы работаем, то есть this. initobj инициализирует каждое поле структуры нулями или null по адресу, которое лежит у нас первым в стеке (а у нас там лежит указатель на this). Дополнительно мы еще передаем токен, который указывает тип структуры. Таким образом получается, что у нас вся структура "перезатерлась нулями" и значение поля A равно нулю.

Tags:
Total votes 2: ↑2 and ↓0+2
Comments4

Articles