2017-07-10 2 views
1

Ich bin ein Objekt serialisieren und beim Zurückladen möchte ich einen bestimmten Wert festlegen, wenn ein Feld fehlt. Wenn beispielsweise ein Feld in Version 2 hinzugefügt wird, möchte ich beim Laden einer Datei, die von Version 1 generiert wurde, einen Wert festlegen.protobuf-net Konstruktor überschreibt deserialisierten Wert

Beispiel:

<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 

Ich habe versucht, den Konstruktor zu verwenden, zu denken, dass es laufen würde, bevor das Feld deserialisiert. Wenn jedoch ein Objekt aus einer serialisierten Datei geladen wird, werden einige Felder mit dem Wert innerhalb der Datei geladen, einige andere Felder bleiben jedoch mit dem vom Konstruktor festgelegten Wert erhalten, und der Wert in der Datei wird ignoriert. Warum passiert das?

PO

+0

Sind die verwirrten Werte zufällig eine Null? Bedeutung: der Konstruktor setzt sie nicht Null, Sie serialisiert sie als Null, und sie deserialisiert als nicht Null? Wenn ja: ein fehlender [DefaultValue (...)]. Alternativ können Sie implizite Null-Standardwerte (RuntimeTypeModel.UseImplicitZeroDefaults) deaktivieren. Für alles andere muss ich eine Art Code sehen. –

+0

Die verwirrten Werte sind eigentlich boolesch. Das Feld im Konstruktor wird auf TRUE festgelegt. Wenn ich das Deserialisieren mit dem Wissen lösche, dass es als FALSE gespeichert wurde, wird das resultierende serialisierte Objekt das Feld auf TRUE festgelegt. –

+0

für diesen Zweck, falsch === Null. –

Antwort

0

standardmäßig (und in Übereinstimmung mit „proto3“, aber nicht „proto2“), protobuf-net annimmt Nullen (und falsch, usw.) als Standardwert (wenn ein Mitglied ist nicht NULL festlegbaren und wenn Es werden keine anderen konditionalen Serialisierungs-APIs erkannt, z. B. das integrierte Muster public bool ShouldSerialize*(). Es hört sich so an, als hätten Sie über den Konstruktor Vorgaben, die nicht Null sind. In diesem Fall müssen Sie protobuf-net nur über das Attribut [DefaultValue(...)] (in System.ComponentModel) über die tatsächlichen Standardwerte informieren. Dies wird auch andere gängige .NET-Tools glücklicher machen, wie PropertyGrid, PropertyDescriptor, usw.).

Alternativ können Sie die implizite Nullstandardfunktion deaktivieren (siehe Kommentare zum Beitrag). Dann werden nur explizite[DefaultValue] Attribute beobachtet.

Verwandte Themen