F#方法返回null而不是Option [英] F# method returns null instead of Option
问题描述
我在 VS2015 $ c上开发
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屋!