【问题标题】:F# Multiple Attributes CLIMutable DataContractF# 多属性 CLIMutable DataContract
【发布时间】:2015-05-04 21:32:17
【问题描述】:

在将 ServiceStack.Redis 与 f# 一起使用时,我遇到了组合属性的问题。也许我在想这个错误,但现在我希望我的类型被序列化为 JSON,但也可以传递给 ServicvStack。 f# 类型的问题是没有默认构造函数,添加到我的 Redis 实例的数据是 emtpy,记录在那里,但里面没有数据。

这是一个例子:

open System
open ServiceStack.Redis

[<CLIMutable>]
[<DataContract>]
type Car = {
    [<field: DataMember(Name="ID")>]
    ID : int64
    [<field: DataMember(Name="Make")>]
    Make : string
    [<field: DataMember(Name="Model")>]
    Model : string
}
let redisCar = redis.As<Car>()

let redisAddCar car : Car =
    let redisCar = redis.As<Car>()
    redisCar.Store({ car with ID = redisCar.GetNextSequence() })

let car1 = redisAddCar { ID = 0L; Make = "Honda"; Model = "Accord LX" }
let car2 = redisAddCar { ID = 0L; Make = "Honda"; Model = "Accord EX" }
let car3 = redisAddCar { ID = 0L; Make = "Honda"; Model = "Accord SX" }

let cars = redisCar.GetAll()
cars |> Seq.iter (fun car -> printfn "ID: %i, Make: %s, Model: %s" car.ID car.Make car.Model)

这将打印出来:

ID: 0, Make: , Model:
ID: 0, Make: , Model:
ID: 0, Make: , Model:

但是,如果我将类型更改为:

[<CLIMutable>]
[<DataContract>]
type Car = {
    [<field: DataMember(Name="ID")>]
    mutable ID : int64
    [<field: DataMember(Name="Make")>]
    mutable Make : string
    [<field: DataMember(Name="Model")>]
    mutable Model : string
}

然后会打印出来:

ID: 1, Make: Honda, Model: Accord LX
ID: 2, Make: Honda, Model: Accord EX
ID: 3, Make: Honda, Model: Accord SX

为什么即使是通过属性定义的,我也必须为每个属性添加可变属性?我希望它不可变,因为我不希望状态改变。也许我想太多了,应该创建一个新类型并将不可变类型转换为可变类型,以便它可以与 ServiceStack.Redis 一起使用?

【问题讨论】:

  • ServiceStack.Redis 正在使用哪个序列化程序?你会遇到这个问题吗? stackoverflow.com/q/20982294/126014 还是这个? blog.ploeh.dk/2013/10/15/…
  • 我没有看到任何指向这些 json 序列化程序的引用。看起来 ServiceStack.Redis 使用了自己的序列化程序github.com/ServiceStackV3/mythz_blog/blob/master/pages/344.md,这可能是问题所在,因为我也在使用 Microsoft 的 DataContract 属性及其内置的 Json 序列化。因此,鉴于您提供的两个链接,我不确定它们是否适用,但它确实表明我可能需要切换 JSON 库以使用内置类库,这在我提供的链接中突出显示:SetConfig(新主机配置 { UseBclJsonSerializers = true});

标签: f# redis servicestack datacontract mutable


【解决方案1】:

CLIMutable 属性不会影响从 F# 代码中使用记录时的记录行为。对于 F# 代码,它仍然是不可变的记录。见这里:http://blogs.msdn.com/b/fsharpteam/archive/2012/07/19/more-about-fsharp-3.0-language-features.aspx

"在 F# 3.0 中,我们添加了 CLIMutableAttribute。如果您附加此 属性为 F# 记录类型,然后 F# 编译器发出一个默认值 构造函数和属性设置器到为这种类型生成的 IL (尽管这些功能不会暴露给 F# 代码)。”

【讨论】:

  • 问题在于它本身可以工作,因为它应该与 DataContract 耦合,它会中断,所以我必须为每个属性设置可变,使其可变。 I.E mutable Make : string 而不是 Make String
猜你喜欢
  • 2011-02-04
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-21
  • 2011-08-20
相关资源
最近更新 更多