F#中的NullReferenceException

Mik*_*icz 1 null f# nullreferenceexception

当我单步执行以下代码时,report第二行为null.但是,第三行生成NullReferenceException.

member this.setTaggedResearchReportList (index : int) (taggedResearchReport : TaggedResearchReportUIVO option) =
    let report = Option.get(taggedResearchReport)
    if not(report.Equals(null)) then
        // do some stuff here
Run Code Online (Sandbox Code Playgroud)

为什么会这样,我该怎么做才能避免呢?谢谢!

后来添加:

这是调用的行this.setTaggedResearchReportList:

getMostRecentTaggedResearchReportForSecurityId (item.id) (new Action<_>(this.setTaggedResearchReportList 0))
Run Code Online (Sandbox Code Playgroud)

这是getMostRecentTaggedResearchReportForSecurityId方法:

let getMostRecentTaggedResearchReportForSecurityId (securityId : int) (callbackUI : Action<_>) =
    getSingleRPCResult<JSONSingleResult<TaggedResearchReportUIVO>, TaggedResearchReportUIVO>
        "TaggedResearchReportRPC"  
        "getMostRecentResearchReportForSecurityId" 
        (sprintf "%i" securityId)
        callbackUI
        (fun (x : option<JSONSingleResult<TaggedResearchReportUIVO>>) ->
            match x.IsSome with
                | true -> Some(Option.get(x).result)
                | false -> None 
        )
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 7

这本身不是答案,而是添加到空处理的讨论中,特别是在与C#代码交互时:我喜欢避免使用该[<AllowNullLiteral>]属性并定义如下的模块来隔离nullF#中的使用码.

[<AutoOpen>]
module Interop =

    let inline isNull value = System.Object.ReferenceEquals(value, null)
    let inline nil<'T> = Unchecked.defaultof<'T>
    let inline safeUnbox value = if isNull value then nil else unbox value
    let (|Null|_|) value = if isNull value then Some() else None

type Foo() = class end

type Test() =
    member this.AcceptFoo(foo:Foo) = //passed from C#
        if isNull foo then nullArg "foo"
        else ...

    member this.AcceptFoo2(foo:Foo) = //passed from C#
        match foo with
        | Null -> nullArg "foo"
        | _ -> ...

    member this.AcceptBoxedFoo(boxedFoo:obj) =
        let foo : Foo = safeUnbox boxedFoo
        ...

    member this.ReturnFoo() : Foo = //returning to C#
        if (test) then new Foo()
        else nil
Run Code Online (Sandbox Code Playgroud)

通常,将这些检查尽可能地靠近API的接口,并且null由于保留了编译器的空检查,您通常可以忘记在F#中.