F# 扩展第三方库中的类型以进行序列化

F# 扩展第三方库中的类型以进行序列化,f#,F#,我需要一个函数来将第三方库中的类型转换为IDictionarys,这样就可以轻松地将它们序列化(转换为JSON)。类型之间存在依赖关系,因此字典有时是嵌套的 现在我有一件可怕的事情: //Example type type A(name) = member __.Name = name //Example type type B(name, alist) = member __.Name = name member __.AList : A list = alist let

我需要一个函数来将第三方库中的类型转换为
IDictionary
s,这样就可以轻松地将它们序列化(转换为JSON)。类型之间存在依赖关系,因此字典有时是嵌套的

现在我有一件可怕的事情:

//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"
这会将所有内容转换为基本类型、此类类型的
IEnumerable
或字典

随着类型的增加,此函数将不断增长(ugh)。它不是类型安全的(需要catch-all模式)。要弄清楚支持哪些类型,需要仔细阅读单片模式匹配

我希望能够做到这一点:

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
键入第三方类型
成员x.ToSerializable()=。。。
设内联可串行化x=
(^T:(可序列化的成员:单位->IDictionary)x)
设x=ThirdPartyType()|>toSerializable//类型扩展不满足静态成员约束

所以,我在这里寻找创造力。有没有更好的方法来写这篇文章来解决我的问题?

这里有一个可能的解决方案来解决类型安全问题,但不一定是您的扩展性问题:

// these types can appear in any assemblies
type A = { Name : string }
type B = { Name : string; AList : A list }
type C(name:string) =
    member x.Name = name
    static member Serialize(c:C) = dict ["Name", box c.Name]

//以下所有代码都放在一个地方
open System.Collections.Generic
类型SerializationFunctions=类结束
当(^s或^t):(静态成员序列化:^t->IDictionary)>t=
(^s或^t):(静态成员序列化:^t->IDictionary)t)
让内联序列化t=serializationHelper t
//未定义自己的序列化方法的每个类型的重载
使用
静态成员序列化(a:a)=dict[“Name”,框a.Name]
静态成员序列化(b:b)=dict[“Name”,box b.Name;“AList”,box(List.map Serialize b.AList)]
设d1=序列化{A.Name=“A”}
让d2=序列化{B.Name=“B”;AList=[{A.Name=“A”}]}
设d3=序列化(C“测试”)

这里有一个可能的解决方案,可以解决类型安全问题,但不一定是扩展性问题:

// these types can appear in any assemblies
type A = { Name : string }
type B = { Name : string; AList : A list }
type C(name:string) =
    member x.Name = name
    static member Serialize(c:C) = dict ["Name", box c.Name]

//以下所有代码都放在一个地方
open System.Collections.Generic
类型SerializationFunctions=类结束
当(^s或^t):(静态成员序列化:^t->IDictionary)>t=
(^s或^t):(静态成员序列化:^t->IDictionary)t)
让内联序列化t=serializationHelper t
//未定义自己的序列化方法的每个类型的重载
使用
静态成员序列化(a:a)=dict[“Name”,框a.Name]
静态成员序列化(b:b)=dict[“Name”,box b.Name;“AList”,box(List.map Serialize b.AList)]
设d1=序列化{A.Name=“A”}
让d2=序列化{B.Name=“B”;AList=[{A.Name=“A”}]}
设d3=序列化(C“测试”)

作为一个快速而明显的想法:使用重载

//Example type
type A(name) = 
  member __.Name  = name

//Example type
type B(name, alist) =
  member __.Name = name
  member __.AList : A list = alist

type Converter =
    static member ToSerializable(a : A) = dict ["Name", box a.Name]
    static member ToSerializable(b : B) = dict ["Name", box b.Name; "AList", box (b.AList |> List.map Converter.ToSerializable)]

正如quick-n-显而易见的想法:使用重载

//Example type
type A(name) = 
  member __.Name  = name

//Example type
type B(name, alist) =
  member __.Name = name
  member __.AList : A list = alist

type Converter =
    static member ToSerializable(a : A) = dict ["Name", box a.Name]
    static member ToSerializable(b : B) = dict ["Name", box b.Name; "AList", box (b.AList |> List.map Converter.ToSerializable)]

有趣的是,这在几年前对我来说可能是显而易见的。我对函数式编程的探索显然与OO有着相应的背离。有趣的是,这在几年前对我来说可能是显而易见的。我对函数式编程的尝试显然与OO有着相应的背离。不幸的是,我不能做
x.Items>Array.map(unbox>>serialize)|>box
。似乎无法强制转换到
^t
,因为
^t要求成员可序列化
@Daniel-对,因为
^t
必须是静态已知的,所以在运行时这样做没有意义。您可能会使用反射。不幸的是,我无法执行
x.Items |>Array.map(unbox>>序列化)|>box
。似乎无法强制转换到
^t
,因为
^t要求成员可序列化
@Daniel-对,因为
^t
必须是静态已知的,所以在运行时这样做没有意义。您可能会改用反射。