使用带有f#类的Protobuf-Net

时间:2014-12-28 15:56:47

标签: f# protobuf-net

我正在玩f#并制作服务器程序以获得乐趣。

我想我可以通过使用f#访问c#数据类来解决这个问题,但我想尝试使用f#语法。

我的f#记录[<CLIMutable>]有效,但f#class出错了

我的测试代码:

open System
open System.IO
open ProtoBuf

[<ProtoContract; Serializable>]
type Point (m_x : int, m_y : int) = 
    [<ProtoMember(1)>]
    member this.x = m_x
    [<ProtoMember(2)>]
    member this.y = m_y

[<EntryPoint>]
let main argv = 
    let p : Point = new Point(10, 10)
    let out = Console.OpenStandardOutput()
    Serializer.Serialize<Point>(out, p)
    printfn "finish"
    0

我得到了以下输出:

Unhandled Exception:
System.InvalidOperationException: Cannot apply changes to property Program+Point.x
  at ProtoBuf.Serializers.PropertyDecorator.SanityCheck (ProtoBuf.Meta.TypeModel model, System.Reflection.PropertyInfo property, IProtoSerializer tail, System.Boolean& writeValue, Boolean nonPublic, Boolean allowInternal) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.PropertyDecorator..ctor (ProtoBuf.Meta.TypeModel model, System.Type forType, System.Reflection.PropertyInfo property, IProtoSerializer tail) [0x00000] in <filename unknown>:0 
...

1 个答案:

答案 0 :(得分:1)

虽然我对Protobuf了解不多,但我怀疑它的序列化无法为类Point字段分配新值,因为在F#中它们默认是不可变的。您可以更改类定义以使用可变字段/属性:

open System
open System.IO
open ProtoBuf

[<ProtoContract; Serializable>]
type Point (m_x : int, m_y : int) = 
    let mutable vx = 0
    let mutable vy = 0
    do
        vy <- m_y
        vx <- m_x

    [<ProtoMember(1)>]
    member this.x with get() = vx and set v = vx <- v
    [<ProtoMember(1)>]
    member this.y with get() = vy and set v = vy <- v

也许它会帮助你。 如果F#记录[]工作,那么也许更容易使用记录? F#中的记录支持成员和类。