F#中的区分联合被编译为抽象类,其选项成为嵌套的具体类 .
type DU = A | B
DU是抽象的,而DU.A和DU.B是具体的 .
使用ServiceStack,可以使用函数自定义类型到JSON字符串和后面的序列化 . 关于DU类型,这是我在C#中如何做到的 .
using ServiceStack.Text;
JsConfig<DU.A>.SerializeFn = v => "A"; // Func<DU.A, String>
JsConfig<DU.B>.SerializeFn = v => "B"; // Func<DU.B, String>
JsConfig<DU>.DeserializeFn = s =>
if s == "A" then DU.NewA() else DU.NewB(); // Func<String, DU>
F#是否了解其受歧视的工会的编制表格?如何在编译时获得F#中的DU.A类型?
typeof<DU> // compiles
typeof<DU.A> // error FS0039: The type 'A' is not defined
typeof<A> // error FS0039: The type 'A' is not defined
我可以很容易地在F#中注册一个用于反序列化的函数 .
open System
open ServiceStack.Text
JsConfig<DU>.RawDeserializeFn <-
Func<_, _>(fun s -> printfn "Hooked"; if s = "A" then A else B)
对于具体类型DU.A和DU.B,是否可以完全在F#中注册序列化函数?
3 回答
虽然所有的行为(抽象类等)不仅仅是一个实现细节,它实际上是由规范定义的,这些东西是不能从F#访问的 - 这是spec的引用
重要的是,“这些方法和属性可能不会从F#中使用” .
F#中的DU是单一类型的事实是其有用性的关键 . F#方法是使用模式匹配:
这应该有效,因为联合案例不仅是C#中的嵌套类型,也是子类型 . 当然,如果ServiceStack没有工作 .
Daniel是正确的,您可以通过为基本类型
DU
注册序列化函数来完成此操作 . 这是一个更全面的例子结果: