Я отредактировал ваш пример кода, чтобы он мог фактически воспроизвести ошибку.
Проблема заключается в том, что, хотя struct
представляется законным неуправляемым типом, путем вложения его в общий тип, он становится «сконструированным типом», который считается управляемым типом. Это связано с тем, что полный тип вашего struct
фактически включает параметр типа, а общие типы - это управляемые типы. То есть тип не только MyStruct
, но и a.b<T>.MyStruct
где T
- это какой-то тип.
Из спецификации языка C# 5, «10.3.8.6 Вложенные типы в общих классах»:
Каждый тип декларации, содержащиеся в декларации общего класса неявно общая декларация типа.
«4.4 Построенные типы» гласит:
типа имя-могут идентифицировать конструируемый тип, даже если он не определяет параметры типа непосредственно. Это может произойти, когда тип вложен в объявление универсального класса, а тип экземпляра содержащего объявления неявно используется для поиска имени и hellip; в небезопасном коде построенный тип не может использоваться в качестве неуправляемого типа.
И от "18,2 типов указателей":
& hellip; тип референта указателя должен быть неуправляемого типом. неуправляемого типа любого типа, который не является опорного типа или составным тип, и не содержит опорного типа или построенные поля типа на любом уровне вложенности.
Другими словами, спецификация языка становится ясно, как то, что MyStruct
является «построен тип», и что вы не можете иметь указатели на построенных типов.
Что касается того, почему спецификация делает эти ограничения, я не разработчик языка, и поэтому я не могу дать окончательного ответа на это. Тем не менее, мне кажется безопасным предположить, что основная проблема здесь заключается в том, что для построенного типа теоретически возможно, чтобы тип не поддавался проверке при компиляции как безопасный для кода unsafe
.
В вашем примере параметр типа T
не используется в MyStruct
. Но это может быть, и это будет явно плохо в контексте указателя unsafe
.
Я интуитивно предположил, что теоретически возможно, чтобы компилятор выполнил дополнительный анализ, чтобы проверить, что MyStruct
можно трактовать как неуправляемый тип, но a) я мог легко ошибаться в этом (разработчики языка и писатели-компиляторы знают много больше о том, что может пойти не так, как в подобных ситуациях, чем я), и б) даже если это теоретически возможно, это будет дополнительным и значительным осложнением в спецификации языка и написании любого компилятора C#.
Этот последний момент является обоснованием ИМХО, достаточным для того, чтобы разработчики языка просто исключили его. В конце концов, многие, если не большинство типов, вложенных в общий тип, все равно будут использовать параметр типового типа, поэтому полезность такого дополнительного анализа и снисхождения, вероятно, ограничена.
@MachineLearning. Неа. Все поля здесь - типы значений - этот ответ относится к строке, которая не является. – afuna
Просьба предоставить хороший [mcve], который надежно воспроизводит описанную вами ошибку. Существует несколько сценариев, которые могут привести к этой ошибке, но никто, о котором я не знаю, начнет с кода, который вы здесь указали. –
@afuna int in struct может быть неназначенным, поэтому я предполагаю, что его значение будет в куче при назначении и, таким образом, будет подчиняться GC как строка в классе. –