What is the correct way to robustly test for null in F#?
I have a mixed F#/C# project built on top of the Unity game engine (which is a closed source mono c# / c++ engine).
I have a F# function that calls a Unity API function that may return null. The Unity function returns null but my F# code fails to detect this (I know this both from the shape of the test data, attaching a debugger, inserting log statements etc). Every null test I write seems to returns false when it should be true. First try:
let rec FindInParents<'t when 't : null> (go : GameObject) =
match go with
| null -> null
| _ ->
let comp = go.GetComponent<'t>() // GetComponent returns null
match comp with
| null -> FindInParents (go.transform.parent.gameObject) // This should be matched but isn't
| _ -> comp // Always this branch
I have also tried the following without success:
let rec FindInParents<'t when 't : null> (go : GameObject) =
if obj.ReferenceEquals (go, Unchecked.defaultof<'t>) then null
else
let comp = go.GetComponent<'t>() // Comp is null
if obj.ReferenceEquals (comp, Unchecked.defaultof<'t>) then FindInParents<'t> (go.transform.parent.gameObject)
else comp // Always this branch
I feel like I'm missing something fundamental here but so far it has eluded me. Any pointers?
Edit: I should also point out that GetComponent always returns a subtype of UnityEngine.Component and is always a reference type. UnityEngine.Component is a subtype of UnityEngine.Object which defines a custom == operator (I don't think this is relevant though because == is should not be called in the second example (see Daniel's answer to [Handling Null Values in F#)