Шаг 175 - Атрибут StructLayoutAttribute

Есть в C# такой хитрый атрибут как StructLayoutAttribute, с помощью него можно задавать расположение членов класса(структуры) как мы хотим. Имеет два конструктора:

StructLayoutAttribute(short)
StructLayoutAttribute(LayoutKind)

Рассмотрим второй конструктор LayoutKind - задаёт расположение членов класса.

public enum LayoutKind

Члены этого перечисления:

Рассмотрим два последние значения. У нас есть следующая структура:

public struct Test
{
	int i;
	byte j;
}

Как вы думаете какой размер будет у неё 5 байт? Вовсе нет, по умолчанию выравнивание у нас идёт по 8. Просто сделаем:

Test s = new Test();
unsafe
{
	Console.WriteLine("size is {0}", sizeof(Test));
}

Здесь мы получим результат 8, но мы можем сделать следующее:

[StructLayout(LayoutKind.Sequential, Pack = 1)]  
public struct Test
{
	int i;
	byte j; 
}

Член Pack отвечает за выравнивание, по умолчанию он равен 8, поэтому мы изменим его значение на 1 и получим структуру которая будет выровнена на границе 1 байта. После чего её размер будет равен уже 5 байтам. С помощью Explicit как я уже говорил можно точно указать расположение членов класса. Пример.

[StructLayout(LayoutKind.Explicit, Pack = 1)]  
public struct Test2
{
	[FieldOffset(0)] public int i;
	[FieldOffset(3)] public byte j; 
}

Теперь уже размер структуры будет равен 4. Но если мы присвоим значение 3 j, то i не будет равно 3. Мы получим число 50331648. Всё это потому что у нас байты хранятся наоборот если помните( типа L(младший байт)H(старший байт). В шестнадцатеричной системе 50331648 будет равно 0x3000000. Не забывайте об этом.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Leonid Molochniy - 01.11.2001