Метод F# возвращает null вместо Option

Разрабатываю F# приложение .net 4.6.1 на VS2015. у меня есть методы:

type CommonHelper = 
    static member SideEffectOnNull act x = if x = null then act(); x else x
    static member SideEffectOnNotNull act x = if x <> null then act(); x else x

...

    static member GetPerformanceCounter ( fname: CounterFullName ) = 

        let getCounterInternal ( counterFullName: CounterFullName ) =
            Log.Information("Getting counter: {category}\\{name}\\{instance} ",  counterFullName.Category, counterFullName.Name, counterFullName.Instance)
            let receivedCategory = PerformanceCounterCategory.GetCategories().FirstOrDefault( fun x -> String.Equals( x.CategoryName, counterFullName.Category.Category, StringComparison.InvariantCultureIgnoreCase ) )
            if receivedCategory = null  then
                Serilog.Log.Warning ( "Category not found: {category}", counterFullName.Category ); null
            else
                let receivedCounters = PerforrmanceCounterProxy.GetPerformanceCountersFromCategoryOrNull counterFullName.Instance receivedCategory
                if receivedCounters = null then 
                    Log.Warning ("Instance not found {name}(instance: {instance}) in category {category}", counterFullName.Name, counterFullName.Instance, counterFullName.Category); null
                else
                    receivedCounters.FirstOrDefault( fun y -> String.Equals( y.CounterName, counterFullName.Name.Name, StringComparison.InvariantCultureIgnoreCase ) ) 
                    |> CommonHelper.SideEffectOnNull ( fun unit -> Log.Warning ("Name {name}(instance: {instance}) not found for category {category}", counterFullName.Name, counterFullName.Instance, counterFullName.Category) )

        getCounterInternal fname
        |> CommonHelper.SideEffectOnNull (fun unit ->Log.Warning( "Getting counter failed: {category}\\{name}\\{instance}", fname.Category, fname.Name, fname.Instance )) 
        |> CommonHelper.SideEffectOnNotNull (fun unit ->Log.Information( "Getting Counter secceed: {category}\\{name}\\{instance}", fname.Category, fname.Name, fname.Instance ))
        |> (fun x -> if x = null then None else Option.Some(x)) 

Но когда я вызываю этот метод, я получаю null вместо option. введите здесь описание изображения Что я делаю не так?


person Maxim Kitsenko    schedule 26.12.2016    source источник
comment
Мое предположение - проблема связана с visual studio 2015. Поскольку бизнес-логика работает хорошо, я думаю, что VS2015 пользовательский интерфейс показывает неверную информацию   -  person Maxim Kitsenko    schedule 27.12.2016
comment
У меня было значение по умолчанию для этого типа, появляющееся при переходе через - default(T) в случае типов значений и null для ссылочных типов.   -  person Asti    schedule 27.12.2016


Ответы (1)


В F# можно представить одно значение DU без данных с константой null во время выполнения. Вы можете указать компилятору сделать это с помощью CompilationRepresentationFlags.UseNullAsTrueValue:

[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type A = B | C of int

printfn "%A" (obj.ReferenceEquals( B, null ))  // will print "true"

В приведенном выше коде значение DU B компилируется в null. Иногда это полезно для целей оптимизации: вместо того, чтобы каждый раз выделять экземпляр, я использую константу. Помогает, если значение используется много.

Таким образом, тип Option использует ту же технику для случая None, поэтому None отображается в отладчике как null.

Когда-нибудь отладчик будет иметь соответствующие точки расширения для реализации этой и других функций F#. До тех пор отладчик говорит на языке C#, а вы выполняете перевод.

person Fyodor Soikin    schedule 27.12.2016
comment
Отладчик работал нормально до VS2015, что случилось? - person scrwtp; 27.12.2016
comment
Вы хотите сказать, что до 2015 года отладчик показывал вам None вместо null? Вы абсолютно уверены? - person Fyodor Soikin; 27.12.2016
comment
Только что проверил, и ты прав. Должно быть, я мысленно заменил Nones на nulls. - person scrwtp; 27.12.2016
comment
О проблеме сообщается здесь: developercommunity.visualstudio .com/content/problem/44030/ и github.com/Microsoft/visualfsharp/ вопросы/3716 - person Mike; 19.04.2018