You can define a computation builder that hides null
checking, but it doesn't give you a very convenient syntax, so I probably wouldn't write it that way. It would be cool if there was some more lightweight syntax for this, because it would be quite useful. Also, the computation builder just propagates the null
, so you would end with a result of type Nullable<bool>
:
nullable { let! u = user
let! i = item
return u.Id == i.AuthorId && security.Does(user).Have(MyPermission).On(i) }
The idea is that the let!
operation calls the rest of the computation only when the argument is not null
. When it is null
, it immediately returns null
as the overall result.
I don't think there is much you could do to make the code nicer. Of course, if it was all written in F#, then none of the values could be null
(because F# declared types do not permit the null
value), but that's a different story.
Another approach in F# would be to declare an active pattern that matches only when a value is not null
. This has the benefit that you won't have any variables that may have null
value in the code, so there is no danger of using a wrong variable and getting NullReferenceException
:
let shouldGrantPermission = function
| NotNull(security:ISecurityService), NotNull(user), NotNull(item) ->
security.Does(user).Have(MyPermission).On(item)
| _ -> true
The declaration of the active pattern is:
let (|NotNull|_|) a = if a <> null then Some(a) else None
However, even this isn't really too much nicer than the direct equivalent of what you have. I guess dealing with null
values is just pain :-). This article by Ian Griffiths has some related ideas, but again, none of them really solves the problem.