I'm trying to make a type extension for MongoDB C# Driver that will return an option type instead of null when trying to execute a query that yields 0 results.
I've run into a few issues on the way, but right now there is just one thing in the way.
Here is the code
[<Extension>]
type Utils () =
[<Extension>]
static member inline tryFindOne(x: MongoCollection<'T>, query) =
match x.FindOne(query) with
| null -> None
| value -> Some value
[<CLIMutable>]
type Entity =
{ Id : ObjectId; Name : string }
static member Create(name) =
{ Id = ObjectId(); Name = name }
The problem of course is that the record type Entity
to the F# compiler does not conform to the type constraint of the extension method( 'T : null
) but I have to have the contraint to be able to pattern match against nulls. Of course it's sort of a nonsensical thing because the type Entity
is very much "nullable" for interop purposes and will be returned as null whenever you try to query a MongoDB collection which yields 0 results. I tried to set the attribute [<AllowNullLiteral>]
but unfortunately it only works with classes. So alas I'm stuck, I could make Entity
into a class instead but I think records are more idiomatic F#.
I think the following should work:
[<Extension>]
type Utils () =
[<Extension>]
static member inline tryFindOne(x: MongoCollection<'T>, query) =
let theOne = x.FindOne(query);
if (box theOne = null) None else Some(theOne)
I have borrowed the idea from Sergey Tihon's post here: https://sergeytihon.wordpress.com/2013/04/10/f-null-trick/
Alternative way to do the null check without boxing:
[<Extension>]
type Utils () =
[<Extension>]
static member inline tryFindOne(x: MongoCollection<Entity>, query) =
let theOne = x.FindOne(query)
if obj.ReferenceEquals(theOne, null) then None else Some(theOne)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.