Настройте структуру так, чтобы она сериализовалась как Int32 - PullRequest
1 голос
/ 01 августа 2011

Я сохраняю данные, используя двоичную сериализацию.Теперь я изменил поле в программе с Int32 на структуру.Но я все еще хочу сохранить поле как Int32 для обратной совместимости.Как мне это сделать?

справочная информация Моя программа портирована из Delphi и использует много массивов.Проблема в том, что списки в Delphi начинают отсчитываться от 1, vilkort усложнил отслеживание индексов, когда я сейчас занимаюсь разработкой на C #. Поэтому я использую структуру, чтобы упростить работу с индексом на основе 1массивы на основе 0, пока я не исправлю всю программу.

Код

    public void Save()
    {
            using (var writer = File.Open(Path, FileMode.Create))
            {
                var serializer = new BinaryFormatter();
                serializer.Serialize(writer, _data);
            }
    }

    private void Load()
    {
        using (var reader = File.Open(Path, FileMode.Open))
        {
                var deserializer = new BinaryFormatter();
                _data = (Foo) deserializer.Deserialize(reader);
        }
    }

public struct Indexer
{
    //0-baserat index
    private int _index;

    public Indexer(int index)
    {
        _index = index;
    }

    static public implicit operator Indexer(int index)
    {
        return new Indexer(index);
    }

    static public implicit operator int(Indexer indexer)
    {
        return indexer._index;
    }

    public override string ToString()
    {
        return (_index + 1).ToString();
    }

    ...
  }

Ответы [ 4 ]

0 голосов
/ 01 августа 2011

ISerializerSurrogate

Это позволит вам контролировать процесс сериализации / десериализации.

0 голосов
/ 01 августа 2011
 int n = YourStruct.SomeIntVar;
 Marshal.WriteInt32(hBuffer, n);

Я не уверен, работает ли это в вашем случае, так как это зависит от того, как вы сериализуете свои данные в архивы. Если вы напрямую манипулируете данными в памяти или разделяете память (hBuffer), приведенный выше фрагмент кода должен помочь.

0 голосов
/ 01 августа 2011

Вы можете добавить устаревшее поле типа Int32, а также иметь поле структуры. Создайте метод с атрибутом [OnDeserialized] (и правильными аргументами) и при некоторых обстоятельствах инициализируйте поле структуры из поля int, например, что поле int отлично от нуля, а структура имеет значение по умолчанию после десериализации, указывая, что данные являются из старого формата.

private int intValue;                // Legacy field
private SomeStruct structValue;      // New field

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
  if (intValue != 0)
  {
      // Old format, initialize struct with int value.
      structValue = new SomeStruct(intValue);
  }
}

Это не совсем элегантно, и есть другие способы, но если вы не возражаете против сохранения двух полей, это один из более простых способов. Обратите внимание, что в приведенном выше коде предполагается, что ноль указывает «пропущенное» значение для старого поля int.

0 голосов
/ 01 августа 2011

Полагаю, единственным способом будет иметь два класса - один со структурой и один с int32. Затем вы можете преобразовать одно в другое после сериализации. Явно указано, что обратной совместимости нет.

...