Страницы

Поиск по вопросам

пятница, 29 ноября 2019 г.

Почему System.String.Empty не null?

#c_sharp


Доброго.

Возможно, мой вопрос ставит в тупик своей некорректностью, но это лишь для того,
чтобы вы прочувствовали то же, что и я.

Я декомпилировал mscorelib.dll v4.0 двумя декомпиляторами (dotPeek и ILSpy), и оба
мне показали, что это поле readonly и НЕ инициализировано в классе. Класс НЕ partial.

Конечно, при выполнении всё нормально и string.Empty is "", но может мне кто-то объяснить
почему так? Где тогда инициализируется поле, если не здесь (static конструктора также
не найдено)? Или эти декомпиляторы что-то не видят?
    


Ответы

Ответ 1



Смотрите, в инициализации базовых частей языка иногда не обойтись без магии. Например, как вы думаете, как можно описать на C# структуры наподобие int? У структуры есть скрытое поле m_value типа... int! У обыкновенных структур это не могло бы быть скомпилировано, но компилятор при компиляции этого класса знает, что это внутренний тип, и обрабатывает его особенным образом. Такая же точно магия случается при использовании string.Empty. В Майкрософтовской реализации JIT-компилятор знает, что string.Empty — специальное значение, и заменяет его на константу. Это нужно для оптимизации: данное поле используется очень часто. В принципе, можно было бы в таком случае и никогда не инициализировать это поле, но тогда рефлексия и отладчики будут видеть «неправильное» значение, что, конечно, нехорошо. Для этого поле всё же отдельно инициализируется средой выполнения, которая тоже знает этот специальный случай. (Почему не через статический конструктор? Можно предположить, что вызов статического конструктора — относительно дорогая вещь, т. к. он обязан совершать глобальную блокировку на случай одновременного вызова статического конструктора в нескольких потоках.) Всё это, конечно, специфика текущей версии реализации компиляторов и рантайм-библиотеки Майкрософт; в других реализациях (например, Mono) в этом конкретном месте может и не быть никакой магии. Лавры первооткрывателя истины принадлежат @Grundy, который «раскопал» точную причину и указал на неё в своём комментарии.

Комментариев нет:

Отправить комментарий