2016-03-30 1 views
5

Ich bemerkte heute eine seltsame Ausgabe von Newtonsoft.Json, ich bin mir nicht sicher, ob es eine Interaktion mit F # -Typen oder etwas, das in C# auch auftreten kann, so habe ich beide markiert . Ich habe eine Liste der folgenden Datensatz serialisiert:Newtonsoft.Json Serialisierung einige Elemente zweimal

type SplitTracker = 
    { 
    [<JsonIgnore>] 
    split   : SplitDefinition 
    mutable start : duration 
    mutable ``end`` : duration 
    mutable lapCount : int 
    mutable duration : duration Option 
    } 

ich serialisiert es mit JsonConvert.SerializeObject und ich erhalte die folgende ungerade Ausgabe:

"splits": [ 
    { 
    "[email protected]": "0.00", 
    "[email protected]": "0.00", 
    "[email protected]": 0, 
    "[email protected]": null, 
    "start": "0.00", 
    "end": "0.00", 
    "lapCount": 0, 
    "duration": null 
    }, 
    { 
    "[email protected]": "0.00", 
    "[email protected]": "0.00", 
    "[email protected]": 0, 
    "[email protected]": null, 
    "start": "0.00", 
    "end": "0.00", 
    "lapCount": 0, 
    "duration": null 
    } 

Wer weiß, warum das passiert sein könnte? Die Daten sind korrekt, die Vervielfältigung von Feldern mit dem "@" Symbol ist das Problem.

Antwort

6

Die Art und Weise, wie Sie Ihren Datensatz definiert haben, ist hier der Übeltäter. Datensatzfelder werden als Eigenschaften verfügbar gemacht - Sie verwenden jedoch veränderbare Eigenschaften. F # wandelt das in eine Klasse um, die Felder für jedes Ihrer Mutables enthält (der Name ist der Eigenschaftsname mit dem Präfix @) und Eigenschaften, die diese auslesen.

Json wird nun versuchen, alle Felder und alle Eigenschaften zu serialisieren - daher erhalten Sie die Duplizierung.

Ausprobieren in F # interaktiv:

type SplitTracker = 
    { 
     mutable start : float 
    } 
let t = typeof<SplitTracker> 
let fields1 = t.GetFields() // This will give you a field '@start' 
let props1 = t.GetProperties() // This will give you a property 'start' 

Kontrast, der mit dem, was man bekommt, wenn eine einfache Aufzeichnung mit:

type SplitTracker2 = 
    { 
     start : float 
    } 
let t2 = typeof<SplitTracker2> 
let fields2 = t2.GetFields() // You will not see any fields 
let props2 = t2.GetProperties() // There is a single property 'start' 

Diese richtig serialisiert soll. Abgesehen davon macht es Ihren Code idiomatischer.

+0

Danke, sieht aus wie ich könnte das mit einem benutzerdefinierten Konverter reparieren, oder vielleicht, wenn ich diesen Algorithmus ohne veränderbare Variablen herausfinden kann – jackmott

+3

Sie können '[]' auf Ihre veränderbaren Felder, so dass das Feld wird ignoriert. – Tarmil

+0

@jackmott: Ich würde wetten, dass es einen Weg gibt, den Algorithmus zu überdenken, um sich nicht auf Mutationen zu verlassen. Im Zweifelsfall hier posten. –