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
必须是静态已知的,所以在运行时这样做没有意义。您可能会改用反射。