Как мне вызвать Redis StringSet() из F#

Я использую StackExchange.Redis для доступа к экземпляру Redis.

У меня есть следующий рабочий код С#:

public static void Demo()
{
    ConnectionMultiplexer connection = ConnectionMultiplexer.Connect("xxx.redis.cache.windows.net,ssl=true,password=xxx");

    IDatabase cache = connection.GetDatabase();

    cache.StringSet("key1", "value");
}

Вот то, что я надеюсь, будет эквивалентным кодом F #:

let Demo() =
   let cx = ConnectionMultiplexer.Connect @"xxx.redis.cache.windows.net,ssl=true,password=xxx"
   let cache = cx.GetDatabase()
   cache.StringSet("key1", "value") |> ignore

Однако это не компилируется - «Нет совпадений перегрузок для метода StringSet». Метод StringSet ожидает аргументы типа RedisKey и RedisValue, и, похоже, в C# происходит некоторое волшебство компилятора для преобразования строк в вызывающем коде в RedisKey и RedisValue. Волшебства, похоже, не существует в F#. Есть ли способ добиться того же результата?


person Kit    schedule 03.12.2014    source источник
comment
Существуют ли операторы RedisKey.op_Implicit и RedisValue.op_Implicit?   -  person Daniel    schedule 03.12.2014
comment
@ Даниэль - похоже. Если я перехожу к определению, я получаю следующее сгенерированное .fsi: type RedisKey = ... static member op_Implicit : key:string -> RedisKey static member op_Implicit : key:byte [] -> RedisKey static member op_Implicit : key: RedisKey -> byte [] статический член op_Implicit : key:RedisKey -> строка   -  person Kit    schedule 03.12.2014
comment
Затем вам нужно будет сделать StringSet(RedisKey.op_Implicit "key1", RedisValue.op_Implicit "value"). Они вызываются автоматически в C#, но не в F#. Вы также можете определить неявный оператор.   -  person Daniel    schedule 03.12.2014
comment
Круто, похоже, это сработает. Если вы опубликуете это как ответ, я отмечу его как таковой и получу вам волшебные межсетевые очки. Спасибо!   -  person Kit    schedule 03.12.2014
comment
Я бы лично расширил строку, чтобы иметь забавы toRedisKey и toRedisVal. Более читаемый, управляемый и понятный, что происходит. Сделайте то же самое для RedisKey для преобразования в строку или что-то еще.   -  person Philip P.    schedule 05.12.2014
comment
Большое спасибо @Daniel, и большое спасибо, Кит, за вопрос   -  person himekami    schedule 03.11.2016


Ответы (1)


Вот рабочий код, большое спасибо @Daniel:

open StackExchange.Redis
open System.Collections.Generic

let inline (~~) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit: ^a -> ^b) x)

let Demo() =
   let cx = ConnectionMultiplexer.Connect @"xxx.redis.cache.windows.net,ssl=true,password==xxx"
   let cache = cx.GetDatabase()

   // Setting a value - need to convert both arguments:
   cache.StringSet(~~"key1", ~~"value") |> ignore

   // Getting a value - need to convert argument and result:
   cache.StringGet(~~"key1") |> (~~) |> printfn "%s"
person Kit    schedule 03.12.2014
comment
У меня аналогичная проблема. У меня есть строковый ключ и значение, в которое я хочу поместить его и получить из Redis. (resultValue) Когда я запускаю это, я получаю: Тип «RedisValue» не поддерживает преобразование в тип «a». Не уверен, что я делаю неправильно. Как сообщить RedisValue.op_Implicit, что это действительно строка? - person Jamie Dixon; 07.09.2017