【发布时间】:2014-09-13 02:55:59
【问题描述】:
有没有办法让 protobuf 序列化/反序列化 F# 的可区分联合?
我正在尝试使用 protobuf 序列化消息。消息是 F# 记录和区分联合。
序列化似乎可以很好地处理记录,但我无法让它与受歧视的工会一起使用。
在下面的代码中,测试 testMessageA 和 testMessageB 是绿色的。测试testMessageDU是红色的。
module ProtoBufSerialization
open FsUnit
open NUnit.Framework
open ProtoBuf
type MessageA = {
X: string;
Y: int;
}
type MessageB = {
A: string;
B: string;
}
type Message =
| MessageA of MessageA
| MessageB of MessageB
let serialize msg =
use ms = new System.IO.MemoryStream()
Serializer.SerializeWithLengthPrefix(ms, msg, PrefixStyle.Fixed32)
ms.ToArray()
let deserialize<'TMessage> bytes =
use ms = new System.IO.MemoryStream(buffer=bytes)
Serializer.DeserializeWithLengthPrefix<'TMessage>(ms, PrefixStyle.Fixed32)
[<Test>]
let testMessageA() =
let msg = {X="foo"; Y=32}
msg |> serialize |> deserialize<MessageA> |> should equal msg
[<Test>]
let testMessageB() =
let msg = {A="bar"; B="baz"}
msg |> serialize |> deserialize<MessageB> |> should equal msg
[<Test>]
let testMessageDU() =
let msg = MessageA {X="foo"; Y=32}
msg |> serialize |> deserialize<Message> |> should equal msg
我尝试在 Message 类型上添加不同的属性,例如 ProtoInclude 和 KnownType,在 MessageA 和 MessageB 类型上添加 CLIMutable,...但似乎没有任何帮助。
我宁愿不必将我的 DU 映射到类以使序列化工作......
【问题讨论】:
-
我真的不知道 F# 是如何表示这些的,就 protobuf-net 在运行时会看到什么而言。如果这里(在库级别)有明显的“修复”,我会很乐意看看 - 但我需要深入了解 F# 在这里做了什么。
-
Afaik F#(总是?)为有区别的联合创建类层次结构。这就是为什么我希望我可以使用 ProtoInclude 属性。现在在反编译器中查看了它,看起来可能需要在 lib 中进行调整才能使其正常工作.. :( 除非有人想出一种不太明显的方法来使其工作。我在这里上传了反编译的代码:codepad.org/DB0CQU4K
标签: f# protobuf-net