F#方法返回null而不是Option [英] F# method returns null instead of Option

查看:130
本文介绍了F#方法返回null而不是Option的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 VS2015 F#应用程序 .net 4.6.1 $ c>。我有方法:

I develop F# application .net 4.6.1 on VS2015. i have methods:

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

我在做什么错了?

But when i call this method i receive null instead of option. What i'm doing wrong?

推荐答案

在F#中,可以在运行时用 null 常量表示DU的一个无数据值。您可以使用 CompilationRepresentationFlags.UseNullAsTrueValue 指示编译器执行此操作:

In F# it is possible to represent one data-less value of a DU with the null constant at runtime. You can instruct the compiler to do so with CompilationRepresentationFlags.UseNullAsTrueValue:

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

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

在上面的代码中,DU值 B 被编译为 null 。有时出于优化目的是很好的:我使用常量而不是每次都分配实例。

In the above code, the DU value B gets compiled to null. This is sometimes nice for optimization purposes: instead of allocating an instance every time, I use a constant. Helps if the value is used a lot.

因此 Option 类型对<$ c使用相同的技术$ c> None 情况,这就是为什么 None 在调试器中显示为 null 的原因。

So the Option type uses this same technique for the None case, and that's why None shows up as null in the debugger.

有一天,调试器将具有适当的扩展点,以实现此功能和其他F#功能。在此之前,调试器会讲C#,然后您就可以进行翻译了。

One day, the debugger will have appropriate extension points to implement this and other F# features. Until then, the debugger speaks C#, and you get to do the translation.

这篇关于F#方法返回null而不是Option的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆