Вопрос

I'm playing tonight with F# and redis. I'm using ServiceStack.redis to connect to MSOpenTech redis running on localhost. For a test purpose I was trying to save price of bitcoin into redis with code like this:

let redis = new RedisClient("localhost")
redis.FlushAll()

let redisBitstamp = redis.As<BitstampLast>()
let last = {Id = redisBitstamp.GetNextSequence(); Timestamp = 1386459953; Value=714.33M}
redisBitstamp.Store(last)

let allValues = redisBitstamp.GetAll()
allValues.PrintDump()

Unfortunately, the result from PrintDump was:

[
    {
            __type: "Program+BitstampLast, RedisSave",
            Id: 0,
            Timestamp: 0,
            Value: 0
    }
]

Just for testing purpose, I ran nearly identical code in C# on same redis instance:

class BitstampLast
{
    public Int64 Id { get; set; }
    public int Timestamp { get; set; }
    public decimal Value { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var redis = new RedisClient("localhost");
        redis.FlushAll();

        var redisBitstamp = redis.As<BitstampLast>();
        var last = new BitstampLast() {Id = redisBitstamp.GetNextSequence(), Timestamp = 1386459953, Value=714.33M};
        redisBitstamp.Store(last);

        var allValues = redisBitstamp.GetAll();
        allValues.PrintDump();

    }
}

And the result...

[
    {
            __type: "CSharpRedis.BitstampLast, CSharpRedis",
            Id: 1,
            Timestamp: 1386459953,
            Value: 714.33
    }
]

So, what am I missing? Why does it work in C#, and doesn't in F#?

EDIT: BitstampLast is defined that way:

type BitstampLast = {Id:int64; Timestamp:int; Value:decimal}

which is wrong, because it should be:

type BitstampLast = {mutable Id:int64; mutable Timestamp:int; mutable Value:decimal}

And now it works. Next questions then - why it should be mutable? Does redis somewehow mess with this object?

Это было полезно?

Решение

Many of ServiceStack's libraries (e.g.Serialization, Auto-mapping, etc) works on POCO's that have a default constructor and writable properties, which F# immutable records don't have by default.

The best way create POCO's in F# is to decorate it with the CLIMutable attribute F# 3.0 Language Feature which creates a POCO type with public getters and setters for all properties that are accessible in C# code, but still behave as immutable types in F#, e.g:

[<CLIMutable>] 
type BitstampLast = { Id:int64; Timestamp:int; Value:decimal }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top