Если GetFields() не гарантирует порядок, как работает LayoutKind.Sequential
Мне нужно получить fieldinfo в гарантированном порядке в отношении порядка объявления. Сейчас я использую атрибуты для указания порядка.
Есть ли более автоматический способ сделать это?
Кто-нибудь знает, как работает LayoutKind.Sequential
, и если я могу применить его технику.
Я не вижу, как работает LayoutKind.Sequential
, если не существует кода прекомпилятора, который добавляет атрибуты.
Ответы
Ответ 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, чтобы они не делали в оптимизации памяти, которая испортила порядок полей.