#.net #f# #c#-to-f#
#.net #f# #c #-to-f#
Вопрос:
Я переношу свой код F # с dotnet3.1 на 5 и борюсь со следующим кодом:
let tryRemove key (dict: Concurrent.ConcurrentDictionary<'a, 'b>) =
match dict.TryRemove(key) with
| (true, v) -> Some v
| (false, _) -> None
В версии 3.1 TryRemove
возвращаемый кортеж, в версии 5 он возвращает только логическое значение. Чтобы получить значение из словаря, мне нужно передать ссылку в качестве второго параметра TryRemove
.
Как правильно это сделать и избежать возврата null v?
Я попробовал следующий код:
let tryRemove key (dict: Concurrent.ConcurrentDictionary<'a, 'b>): 'b option =
let mutable v: 'b = null
match dict.TryRemove(key, amp;v) with
| true -> Some v
| _ -> None
Но теперь функция, которая его использует, считает, что внутри этой опции можно иметь значение null из tryRemove
ошибка FS0001: тип ‘(Body -> unit)’ не имеет ‘null’ в качестве правильного значения
где b' is (Body -> unit)
Ответ №1:
Проблема в том, что .NET 5 добавил перегрузку. Раньше была только TryRemove (key : 'a, byref<'b> value) : bool
, теперь TryRemove(item: KeyValuePair<'a, 'b>) : bool
выбирается новая перегрузка. Смотрите netcore 3.1 против NET 5
Альтернативным решением является добавление аннотации типа, например
let tryRemove (key: 'a) (dict: Concurrent.ConcurrentDictionary<'a, 'b>) =
match dict.TryRemove(key) with
| (true, v) -> Some v
| (false, _) -> None
Ответ №2:
Я только что выяснил:
let mutable v = Unchecked.defaultof<'b>
вместо
let mutable v: 'b = null
работает, но это очень странно. упрощенный синтаксис с последним аргументом out, переведенным в результат кортежа, больше не работает. Так ли это?
РЕДАКТИРОВАТЬ
Это все еще работает! Смотрите правильный ответ 🙂