У меня есть эта примерная подпись функции:
let func1 (input:'a when 'a :> (IReadOnlyDictionary<string, string>)) =
...
Я также хотел бы разрешить 'a
быть IDictionary<string, string>)
. Таким образом, любой тип может быть передан. Код, использующий параметр input
, вызывает TryGetValue
, который поддерживают оба интерфейса.
Можно ли указать ограничение типа ИЛИ, подобное этому? Если да, то каков конкретный синтаксис для этого?
Я почти уверен, что вы не можете, но вы можете использовать SRTP, чтобы запросить метод TryGetValue
:
let inline func1 (input : 'a when 'a : (member TryGetValue : string * byref<string> -> bool)) =
let mutable value = ""
let flag = input.TryGetValue("key", &value)
flag, value
Это некрасиво, но это работает. Здесь это называется с помощью IDictionary
:
dict [ "key", "value" ]
|> func1
|> printfn "%A" // (true, "value")
И здесь это называется IReadOnlyDictionary
:
dict [ "key", "value" ]
|> System.Collections.ObjectModel.ReadOnlyDictionary
:> System.Collections.Generic.IReadOnlyDictionary<_, _>
|> func1
|> printfn "%A" // (true, "value")
@brian-berns Это сработало отлично! Я был рад узнать, как указать ограничение для метода TryGetValue
. Я пытался, но не мог понять часть значения out. Я определенно забрел в глубокий конец с этим. Я заметил, что в F# методы типа Try из .NET framework автоматически переписываются или перекомпилируются для возврата кортежа bool * T вместо использования метода out value. Я предполагаю, что компилятор не будет знать о таком случае, поэтому интересно узнать, что F# может выдавать значения, когда это необходимо.
Действительно. Можно написать
let func1 (input: 'a when 'a :> (IReadOnlyDictionary<string,string>) and 'a :> (IDictionary<string,string>)) =
, но это не сработает, потому что два интерфейса не реализованы одновременно, даже дляSystem.Collections.Generic.Dictionary<_,_>
. И не допускается дизъюнкция в ограничениях типа. Таким образом, выбор нужных элементов, как показано выше, должен работать. И вы можете использовать конструкциюand
для объединения нескольких таких ограничений членов.