Мне кажется, что некоторые свойства типа опции F # не видны из проектов С#. Проверяя типы, я могу видеть более или менее причину, но я не совсем понимаю, что именно происходит, почему эти выборы были сделаны или как лучше всего обойти проблему.
Вот некоторые фрагменты, демонстрирующие проблему. У меня есть решение VS2015, содержащее два проекта, проект С# и проект F #. В проекте F # у меня есть класс, определяемый следующим образом:
type Foo () =
member this.Bar () = Some(1)
Кроме того, в F # я могу написать что-то вроде этого:
let option = (new Foo()).Bar()
let result = if option.IsNone then "Is none" else "Is some"
Итак, похоже, что тип опции имеет свойство с именем IsNone
. Теперь, в проекте С#, у меня есть ссылка на .dll, скомпилированный из проекта F #. Это позволяет мне писать, например,
var optionType = new Foo().Bar();
Переменная optionType
- это FSharpOption<int>
. Как я уже отмечал выше, когда я использую типы опций в проектах F #, я обычно имею доступ, например, к свойствам IsSome
и IsNone
. Однако, когда я пытаюсь написать что-то вроде optionType.IsNone
, я получаю ошибку CS1546 "Свойство, индекс или событие... не поддерживается языком". В соответствии с этим Intellisense не обнаруживает свойство:
Теперь, когда вы проверяете тип FSharpOption, я вижу, что свойства IsNone и IsSome отображаются как статические методы:
С другой стороны, когда я проверяю тип из F #, вместо этого я вижу следующее:
Здесь "существование" свойств IsSome
и IsNone
очевидно. Наводя курсор на эти свойства, VS2015 дает мне следующее примечание: "Содержащий тип может использовать" null "в качестве значения представления для своего случая с унифицированным объединением. Этот член будет скомпилирован как статический член". Именно по этой причине свойства недоступны, кроме как статические методы (как отмечают Лукев и Федор Сойкин).
Итак, ситуация выглядит так: Скомпилированный тип FSharpOption не имеет никаких свойств IsNone и IsSome. Что-то происходит за кулисами в F #, чтобы активировать эмуляцию этих свойств.
Я знаю, что обойти это можно, используя OptionModule
в Microsoft.FSharp.Core. Однако, похоже, что эта функциональность является сознательным выбором для архитекторов основной библиотеки F #. Каковы причины выбора? И использует OptionModule
правильное решение, или есть лучший способ использовать тип FSharpOption<T>
из С#?