если GetFields () не гарантирует порядок, как работает LayoutKind.Sequential - PullRequest
19 голосов
/ 09 ноября 2011

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

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

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

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

Ответы [ 3 ]

15 голосов
/ 09 ноября 2011

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

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

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

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

3 голосов
/ 01 июля 2013

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

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

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

0 голосов
/ 09 ноября 2011

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

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

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

...