Исходный код SSCLI20 для clr / src / vm / class.cpp, MethodTableBuilder :: HandleExplicitLayout может предоставить некоторую информацию. Это необычно сильно комментируется, этот комментарий описывает правила (отредактированы для удобства чтения):
// go through each field and look for invalid layout
// (note that we are more permissive than what Ecma allows. We only disallow
// the minimum set necessary to close security holes.)
//
// This is what we implement:
//
// 1. Verify that every OREF is on a valid alignment
// 2. Verify that OREFs only overlap with other OREFs.
// 3. If an OREF does overlap with another OREF, the class is marked unverifiable.
// 4. If an overlap of any kind occurs, the class will be marked NotTightlyPacked (affects ValueType.Equals()).
Правило 1 гарантирует, что эталонное назначение остается атомарным. Правило 2 говорит, почему вы можете делать то, что делали, любая ссылка на тип объекта может перекрываться. Наложение перекрытия со значением типа значения не допускается, что приводит к повреждению сборщика мусора. Правило 3 гласит следствие: оно только делает тип не подлежащим проверке.
В противном случае это не единственный способ испортить строку без ключевого слова unsafe . Просто вызовите функцию, которая топает строку. Он получает указатель на содержимое строки в куче GC или в куче загрузчика (интернированные строки), копия не создается. Это также не поддающийся проверке код и такой же неиспользуемый при работе в песочнице.
Суть дела: ключевое слово C # unsafe вовсе не связано с тем, что CLR считает проверяемым, и, следовательно, фактически безопасным кодом. Он заботится о вопиющих случаях, используя указатели или пользовательские типы значений (фиксированные). Является ли это утечка в C # языка спецификации спорно. Pinvoke - более очевидный крайний случай. Привязка к функции операционной системы довольно опасна. Пинковать какую-то стороннюю библиотеку С нет.
Но я должен согласиться с @fej, [FieldOffset] должен был пройти курс лечения "ты уверен". Жаль, что для этого нет синтаксиса. По общему признанию, я еще не выяснил, почему это действительно должно влиять на управляемый макет. Было бы намного больше смысла, что этот атрибут будет применяться только к маршалированной компоновке. Странно, кто-то держал туза за рукав в первые дни, может быть.