2010-05-20 8 views
1

J'essaie de sérialiser le type "vectoriel" (Microsoft.FSharp.Math). Et je reçois cette erreur:Comment JSON sérialiser le type de vecteur mathématique dans F #?

Exception Details: System.Runtime.Serialization.SerializationException: Type '[email protected]' with data contract name 'Instances.FloatNumerics_x0040_115: http://schemas.datacontract.org/2004/07/Microsoft.FSharp.Math ' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

J'ai essayé de mettre l'attribut KnownType et d'autres choses, mais rien n'y fait!

Quelqu'un pourrait-il connaître la réponse? Ce est le code que j'utilise:

// [< KnownType(typeof<vector>) >] 
type MyType = vector    

let public writeTest = 
    let aaa = vector [1.1;2.2] 
    let serializer = new DataContractJsonSerializer(typeof<MyType>) 
    let writer = new StreamWriter(@"c:\test.txt") 
    serializer.WriteObject(writer.BaseStream, aaa) 
    writer.Close() 

Répondre

5

Je pense que F # de type vector ne fournit pas tout le soutien nécessaire pour la sérialisation JSON (et est tout à fait un type complexe en interne). Peut-être que la meilleure chose à faire dans votre cas serait de le convertir en un tableau et de sérialiser le tableau (ce qui génèrera certainement un JSON plus court et plus efficace).

La conversion est assez simple:

let aaa = vector [1.1;2.2] 
let arr = Array.ofSeq aaa // Convert vector to array 

// BTW: The 'use' keyword behaves like 'using' in C# 
use writer = new StreamWriter(@"c:\test.txt") 
let serializer = new DataContractJsonSerializer() 
serializer.WriteObject(writer.BaseStream, aaa) 

Pour convertir le tableau arrière à vecteur, vous pouvez utiliser Vector.ofSeq (qui est une contrepartie de Array.ofSeq utilisé dans l'exemple ci-dessus).

+0

Bon point et pur, mais que faire si le vecteur fait partie d'une structure plus grande et que je veux sérialiser toute la structure et non pas champ par champ? –

4

Vous pouvez également utiliser:

let v = vector [1.;3.]; 
let vArr = v.InternalValues 

pour obtenir le tableau interne du vecteur. De cette manière, vous n'avez pas besoin de créer un tableau temporaire.

Types, RowVector, Matrix possède également cette méthode pour obtenir les tableaux internes.

+0

Bon point! Mais c'est plus comme un hack. –

Questions connexes