J'ai besoin d'une fonction pour convertir les types d'une bibliothèque tierce en IDictionary
s afin qu'ils puissent être facilement sérialisés (en JSON). Il existe des dépendances entre les types, de sorte que les dictionnaires sont parfois imbriqués.Extension des types dans la bibliothèque tierce pour la sérialisation
En ce moment j'ai quelque chose de hideux comme ceci:
//Example type
type A(name) =
member __.Name = name
//Example type
type B(name, alist) =
member __.Name = name
member __.AList : A list = alist
let rec ToSerializable x =
match box x with
| :? A as a -> dict ["Name", box a.Name]
| :? B as b -> dict ["Name", box b.Name; "AList", box (List.map ToSerializable b.AList)]
| _ -> failwith "wrong type"
Cela transformerait tout à un type primitif, un IEnumerable
d'un tel type, ou un dictionnaire.
Cette fonction continuera de croître au fur et à mesure de l'ajout de types (pouah). Ce n'est pas sécurisé pour la saisie de type (nécessitant le schéma fourre-tout). Déterminer quels types sont pris en charge nécessite de parcourir la correspondance de modèle monolithique.
J'aimerais pouvoir faire ceci:
type ThirdPartyType with
member x.ToSerializable() = ...
let inline toSerializable x =
(^T : (member ToSerializable : unit -> IDictionary<string,obj>) x)
let x = ThirdPartyType() |> toSerializable //type extensions don't satisfy static member constraints
Donc, je suis à la recherche de créativité ici. Y a-t-il une meilleure façon d'écrire ceci qui répond à mes plaintes?
+1 C'est une utilisation intelligente des contraintes de membres statiques! – Daniel
Malheureusement, je ne peux pas faire 'x.Items |> Array.map (unbox >> sérialiser) |> box'. Il semble qu'il n'y ait aucun moyen de transformer en '^ t' où'^t requiert un membre ToSerializable'. – Daniel
@Daniel - à droite, parce que 't 'doit être connu statiquement, donc cela n'a pas de sens de le faire à l'exécution. Vous pourriez potentiellement utiliser la réflexion à la place. – kvb