Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

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

Anna | 17.06.2014 | нет комментариев
При работе с отражением (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();

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

  • Частичная сериализация (обновление определенного поля через сеть, упорядочивание по имени может иметь второстепенный результат при рефакторинге)
  • Маппинг в другие типы
  • Маппинг в другие языки
  • Порядок отображения полей в инструментарии (визуальный порядок будет совпадать с порядком в коде)
Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB