Подтвердить что ты не робот

Если GetFields() не гарантирует порядок, как работает LayoutKind.Sequential

Мне нужно получить fieldinfo в гарантированном порядке в отношении порядка объявления. Сейчас я использую атрибуты для указания порядка.

Есть ли более автоматический способ сделать это?

Кто-нибудь знает, как работает LayoutKind.Sequential, и если я могу применить его технику.

Я не вижу, как работает LayoutKind.Sequential, если не существует кода прекомпилятора, который добавляет атрибуты.

4b9b3361

Ответ 1

Если вы хотите, чтобы упорядочение полей, возвращаемых Type.GetFields, было стабильным, попробуйте выполнить сортировку с помощью свойства MetadataToken.

Type myType = ...
BindingFlags flags = ...
IEnumerable<FieldInfo> orderedFields = myType.GetFields(flags)
                                             .OrderBy(field => field.MetadataToken);

Эмпирически, упорядочивая поля таким образом, было найдено вернуть их в порядке объявления, , хотя это не документировано.

Кстати, заданный вопрос не имеет смысла; нет никаких оснований полагать, что API отражения каким-либо образом привязан к тому, как среда выполнения хранит объекты в памяти.

Ответ 2

Вопрос старый, но не такой старый... Я имею дело с той же проблемой. И я предпочитаю получать поля в порядке декларации. Следующий вызов должен работать для типа значения или форматированного ссылочного типа.

var fields = type.GetFields().OrderBy(f => Marshal.OffsetOf(type, f.Name).ToInt32());

Наслаждайтесь!

Ответ 3

LayoutKind.Sequential указывает, что поля типа должны быть выложены в памяти в том же порядке, в каком они объявлены в вашем исходном коде.

Без атрибута CLR может оптимизировать использование памяти, переставляя поля.

Таким образом, атрибут просто добавляет метаданные, которые сообщают CLR, чтобы они не делали в оптимизации памяти, которая испортила порядок полей.