How can I match a list of .NET type for null in a F# record type?

Viewed 345

I have a class defined in C#:

public class Foo
{
    public string Bar { get; set; }
}

Then I define a record type in F# with a method returning a new object:

type Bar =
    {
        FooList: Foo list
    }
    member this.FromBarList(barList: string list) =
        let fooListNotNull =
            match this.FooList with
            | [] -> []
            | _ -> this.FooList |> List.filter (fun x -> (List.contains x.Bar barList ) )
        {
            FooList = fooListNotNull
        }

Since the type 'Bar' will be used in C# code, the property FooList can be null, and I'd like to check for it. But I'm getting the error:

The type 'Foo list' does not have 'null' as a proper value

Despite I find this type of matching in docs: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/values/null-values

How can I match null correctly?

2 Answers

'a list is an F# type, hence not nullable. I believe there is some implicit conversion here, but the actual type of a C# list is System.Collections.Generic.List<'T>, which is nullable. It is conveniently aliased as ResizeArray<'T> in F#.

Replace Foo list with ResizeArray<Foo>, then the snippet you provide should at least compile.

It is possible to make a null F# list within F# and presumably in C# too:

let nullList = Unchecked.defaultof<int list>

You can check for null but you need to box it first:

match box nullList with
| null -> []
| _ -> nullList

Here's a generic function to do this for any value:

let defaultNull defaultValue x =
    match box x with
    | null -> defaultValue
    | _ -> x

This is how you would use it in your case:

nullList |> defaultNull []
Related