2017-07-10 1 views
1

オブジェクトをシリアル化しています。ロードするときに、フィールドがない場合は特定の値を設定します。たとえば、バージョン2でフィールドが追加された場合、バージョン1で生成されたファイルをロードするときに、値を設定したいとします。protobuf-netデシリアライズされた値をオーバーライドするコンストラクタ

例:

<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

+0

混乱している値は何時でもゼロですか?意味:コンストラクタはそれらをゼロ以外に設定し、それらをゼロとしてシリアル化し、非ゼロとして非直列化しますか?もしそうなら:[DefaultValue(...)]がありません。または、暗黙のゼロのデフォルト値(RuntimeTypeModel.UseImplicitZeroDefaults)を無効にします。他のものについては、何らかのコードを見る必要があります。 –

+0

混乱している値は実際にブール値です。コンストラクタのフィールドはTRUEに設定されます。それがFALSEとして保存されていることを知ってデシリアライズすると、結果として得られるデシリアライズされたオブジェクトのフィールドはTRUEに設定されます。この目的のために –

+0

、偽===ゼロ。 –

答えて

0

(および「proto3」ではなく、「proto2」に沿って)、いるProtobufネットは、(などと虚偽の)ゼロを想定して、デフォルト値として(メンバーがNULL可能でないと組み込みのpublic bool ShouldSerialize*()パターンなど、他の条件付きシリアル化APIは検出されません)。この場合、コンストラクタを介してゼロ以外のデフォルト値が設定されているように聞こえます。その場合は、属性[DefaultValue(...)]System.ComponentModel)を使ってprotobuf-netに実際のデフォルト値を伝えるだけです。これにより、PropertyGrid,PropertyDescriptorなど、他の一般的な.NETツールもより幸せになります。

また、暗黙のゼロデフォルト機能を無効にすることもできます(記事のコメントを参照)。その後、明示的[DefaultValue]属性のみが守られます。

関連する問題