当类具有隐式运算符时,使用BinaryFormatter进行序列化/反序列化

时间:2018-10-24 07:14:58

标签: c# implicit-conversion binaryformatter

在服务器和客户端之间传输时,我们使用BinaryFormatter将对象转换为字节。

我们需要传输的所有类都使用[Serializable]属性,它通常可以正常工作。反序列化时,我们还使用自己的SerializationBinder将其映射到正确的对象类型和程序集。

但是当序列化/反序列化任何具有隐式运算符的对象时,我们会遇到问题。 反序列化时,它是根据操作员的类型和值来执行的,因此可能会丢失信息。 因此,例如,一个具有两个属性和一个隐式运算符的类,它将尝试从隐式运算符类型反序列化对象,而这两个属性的值似乎丢失了。

如何强制它像其他任何类一样正常运行?还是我错过了什么?

更新

进行进一步调查时,似乎是包装器类的组合,该包装器类使用返回某些类型的隐式运算符来实现ISerializable和child属性。

示例:

[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 :(得分:0)

该问题的解决方案是对AddValue()使用重载方法,其中显式设置了类型,如下所示:

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

这解决了问题。