Я пытался строить-структуру (SA
) с помощью [StructLayout(LayoutKind.Explicit)]
, который имел поле, которое является еще одним struct
(SB
)..NET поведение LayoutKind.explicit для поля, которое само по себе является STRUCT
Первый: Я был удивлен, мне было позволено заявить, что другой без [StructLayout(LayoutKind.Explicit)]
-структуру, в то время как в SA
, все поля MUST имеют [FieldOffset(0)]
или компилятор будет кричать. Это не имеет большого смысла.
- Является ли это лазейкой в предупреждениях/ошибках компилятора?
Второй: кажется, что все ссылки (object
) поля в SB
перемещаются в передней части SB
.
- Это поведение описывается в любом месте?
- Это зависит от реализации?
- Определяется ли он везде, где он зависит от реализации?
:)
Примечание: Я не намерен использовать это в рабочем коде. Я задаю этот вопрос в основном из любопытства.
Экспериментирование
// No object fields in SB
// Gives the following layout (deduced from experimentation with the C# debugger):
// | f0 | f4 and i | f8 and j | f12 and k | f16 |
[StructLayout(LayoutKind.Explicit)]
struct SA {
[FieldOffset(0)] int f0;
[FieldOffset(4)] SB sb;
[FieldOffset(4)] int f4;
[FieldOffset(8)] int f8;
[FieldOffset(12)] int f12;
[FieldOffset(16)] int f16;
}
struct SB { int i; int j; int k; }
// One object field in SB
// Gives the following layout:
// | f0 | f4 and o1 | f8 and i | f12 and j | f16 and k |
// If I add an `object` field after `j` in `SB`, i *have* to convert
// `f4` to `object`, otherwise I get a `TypeLoadException`.
// No other field will do.
[StructLayout(LayoutKind.Explicit)]
struct SA {
[FieldOffset(0)] int f0;
[FieldOffset(4)] SB sb;
[FieldOffset(4)] object f4;
[FieldOffset(8)] int f8;
[FieldOffset(12)] int f12;
[FieldOffset(16)] int f16;
}
struct SB { int i; int j; object o1; int k; }
// Two `object` fields in `SB`
// Gives the following layout:
// | f0 | f4 and o1 | f8 and o2 | f12 and i | f16 and j | k |
// If I add another `object` field after the first one in `SB`, i *have* to convert
// `f8` to `object`, otherwise I get a `TypeLoadException`.
// No other field will do.
[StructLayout(LayoutKind.Explicit)]
struct SA {
[FieldOffset(0)] int f0;
[FieldOffset(4)] SB sb;
[FieldOffset(4)] object f4;
[FieldOffset(8)] object f8;
[FieldOffset(12)] int f12;
[FieldOffset(16)] int f16;
}
struct SB { int i; int j; object o1; object o2; int k; }
Если я не ошибаюсь, у структуры также есть «макетированный макет», когда мы бросаем необработанный небезопасный указатель на указатель на эту структуру, не так ли? Скажем, в 'unsafe {SA * sa = (SA *) 0x1234;/* Использовать sa здесь * /} ',' sa' будет иметь тот же макет, что и при его сортировке, не так ли? –
Нет, это не маршалинг. Компилятор не позволит вам это сделать, структура не будет ослабляться. Попробуй. –
Действительно, он работает с structs, содержащим только int, но не при добавлении поля объекта. Однако вопрос сохраняется для структур, которые содержат только 'int' и такие, как первый, который я использовал. –