F# Multiple Attributes CLIMutable DataContract

血红的双手。 提交于 2019-12-12 03:59:13

问题


I am running into an issue with combining attributes when using ServiceStack.Redis with f#. Maybe I am thinking about this wrong but right now I'd like my type to be seralized to JSON but also passable to ServicvStack. The issue with f# types is that there is no default constructor and this the data added to my Redis instance is emtpy, well the record is there but none of the data inside it is there.

Here is an example:

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)

This will print out:

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

However if I change the type to this:

[<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
}

It will then print out:

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

Why do I have to add mutable to each property even if it was defined through the attribute? I'd prefer it to not be mutable, as I don't want the state to change. Maybe I am thinking about this too much and should just make a new type and translate the immutable type to the mutable type so it can be consumed with ServiceStack.Redis?


回答1:


CLIMutable attribute doesn't affect record behavior when record is used from F# code. For F# code it is still immutable record. See here: http://blogs.msdn.com/b/fsharpteam/archive/2012/07/19/more-about-fsharp-3.0-language-features.aspx

"In F# 3.0, we’ve added CLIMutableAttribute. If you attach this attribute to an F# record type, then the F# compiler emits a default constructor and property setters into the generated IL for this type (though those features are not exposed to F# code)."



来源:https://stackoverflow.com/questions/28845241/f-multiple-attributes-climutable-datacontract

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!