繁体   English   中英

F#方法返回null而不是Option

[英]F# method returns null instead of Option

我在VS2015上开发了F# application .net 4.6.1 我有方法:

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 在此输入图像描述 我做错了什么?

在F#中,可以在运行时使用null常量表示DU的一个无数据值。 您可以使用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#,你可以进行翻译。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM