Порядок полей в соответствии с порядком в коде (C#)

от автора

При работе с отражением (Reflection) порядок отраженных полей не гарантируется. Обычно это не имеет значения, но иногда нужен порядок в точном соответствии порядку определенному в коде. Например, это бывает необходимо для частичной сериализации.
Для решения этой надуманной проблемы мы воспользуемся сервисами межъязыкового взаимодействия.

Для начала мы пометим класс атрибутом StructLayoutAttribute с параметром LayoutKind.Sequential. Это заставит компилятор расположить поля в неуправляемой памяти в порядке объявленном в коде. После этого мы отсортируем отраженные поля по смещению относительно начала класса с помощью метода Marshal.OffsetOf.

Пример тестового класса:

[StructLayout(LayoutKind.Sequential)] public class TestClass1 {     public int Value1;     public string Value2;     public bool Value3; } 

Пример сортировки отраженных полей:

      Type type = typeof(TestClass1);       List<FieldInfo> fields = new List<FieldInfo>(type.GetFields());        // исходный порядок       foreach (FieldInfo field in fields)         Console.WriteLine(field.Name);       Console.WriteLine();        // сортируем по типам (сбиваем порядок)       fields.Sort(         delegate(FieldInfo _first, FieldInfo _second)         {           int first = _first.FieldType.GetHashCode();           int second = _second.FieldType.GetHashCode();           return first.CompareTo(second);         }       );        foreach (FieldInfo field in fields)         Console.WriteLine(field.Name);       Console.WriteLine();        // сортируем по размещению в коде       fields.Sort(         delegate(FieldInfo _first, FieldInfo _second)         {           int first = Marshal.OffsetOf(type, _first.Name).ToInt32();           int second = Marshal.OffsetOf(type, _second.Name).ToInt32();           return first.CompareTo(second);         }       );        foreach (FieldInfo field in fields)         Console.WriteLine(field.Name);       Console.WriteLine(); 

В каких же случаях может понадобится такое? Скажу честно, в очень редких. Не рекомендуется писать какой-либо код, зависящий от порядка, но все же бывает когда это может пригодится:

  • Частичная сериализация (обновление конкретного поля через сеть, упорядочивание по имени может иметь побочный эффект при рефакторинге)
  • Маппинг в другие типы
  • Маппинг в другие языки
  • Порядок отображения полей в инструментарии (визуальный порядок будет совпадать с порядком в коде)

ссылка на оригинал статьи http://habrahabr.ru/post/201584/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *