Сериализация / десериализация с помощью BinaryFormatter, когда у класса есть неявный оператор - PullRequest
0 голосов
/ 24 октября 2018

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

Все классы, которые нам нужно передать, используют атрибут [Serializable], и он обычно работает так, как должен.Мы также используем наш собственный SerializationBinder при десериализации, чтобы сопоставить его с правильным типом объекта и сборкой.

Но у нас есть проблема при сериализации / десериализации любого объекта, который имеет неявный оператор.При десериализации он делает это из типа и значения оператора и, таким образом, потенциально теряет информацию.Так, например, класс с двумя свойствами и одним неявным оператором будет пытаться десериализовать объект из неявного типа оператора, а значения из двух свойств, похоже, будут потеряны.

Как я могу заставить его вести себякак обычно, как любой другой класс?Или я что-то упустил?

Обновление

При дальнейшем исследовании это похоже на сочетание класса-оболочки, реализующего свойство ISerializable и потомка, с использованием неявного оператора, возвращающего определенные типы.

пример:

[Serializable]
    class Dto
    {
        public int MyNumber { get; set; }

        // The implicit operator returning an int will be used when deseralized instead of the complete object
        // If you change it to the operator returning a string, it will not be used at all.
        // Other types like decimal will also trigger the problem, and if multiple are present the int seems to be one that is used.

        public static implicit operator int(Dto dto) => dto.MyNumber;
        //public static implicit operator string(Dto dto) => dto.MyNumber.ToString();
        //public static implicit operator decimal(Dto dto) => (decimal)dto.MyNumber;
    }

    [Serializable]
    class DtoWrapper : ISerializable
    {
        public Dto Dto { get; set; }

        public DtoWrapper() { }

        public DtoWrapper(SerializationInfo info, StreamingContext context)
        {
            Dto = (Dto)info.GetValue(nameof(Dto), typeof(Dto));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(nameof(Dto), Dto);
        }
    }

При первой сериализации, а затем десериализации экземпляра класса DtoWrapper возникнет ошибка, что свойство Dto не может быть установлено из целого числа.

1 Ответ

0 голосов
/ 25 октября 2018

Решением проблемы было использование метода перегрузки для AddValue (), где тип явно установлен, например:

info.AddValue(nameof(Dto), Dto, typeof(Dto));

Это решило проблему.

...