protobuf-net 构造函数覆盖反序列化值

protobuf-net Constructor overriding deserialized value

我正在序列化一个对象,当加载回来时,如果某个字段丢失,我想设置一个特定的值。比如在版本2上添加了一个字段,当加载一个版本1生成的文件时,我想设置一个值

示例:

<ProtoContract()>
Public Class Settings

    '  ... other members

    <ProtoMember(33)>
    Public AutoZoom As Boolean 


    'Load from a file
    Friend Shared Function Load(filePath as string) As Settings

        Dim result As Settings

        Try
            If IO.File.Exists(filePath) Then
                Using s As New IO.FileStream(filePath, IO.FileMode.Open)
                    result = Serializer.Deserialize(Of Settings)(s)
                End Using
            Else
                result = CreateNew()
            End If
        Catch ex As Exception
            result = CreateNew()
        End Try

        Return result

    End Function

    Public Shared Function CreateNew() As Settings

        Dim n = New Settings()
        Return n

    End Function        

    Private Sub New()

        AutoZoom = TRUE

    end sub         

End Class

我尝试使用构造函数,认为它会 运行 在字段被反序列化之前。但是碰巧从序列化文件中加载对象时,有些字段会加载文件内部的值,而另一些字段会保留构造函数设置的值,文件内部的值将被忽略。 为什么会这样?

PO

默认情况下(与 "proto3" 一致,但不符合 "proto2"),protobuf-net 假定零(和 false 等)作为默认值(当成员不可为空且当没有检测到其他条件序列化 API,例如内置的 public bool ShouldSerialize*() 模式)。听起来您通过构造函数获得了非零默认值,在这种情况下,您需要做的就是通过属性 [DefaultValue(...)](在 System.ComponentModel 中)告诉 protobuf-net 实际默认值。这也将使其他常见的 .NET 工具更快乐,例如 PropertyGridPropertyDescriptor 等)。

或者,禁用隐式零默认值功能(参见 post 上的注释)。那么只有 explicit [DefaultValue] 属性会被观察到。