我有以下c#代码,它检查权限.我想知道,当转换为f#时,计算表达式是否是一种分解空检查的方法.
bool ShouldGrantPermission(ISecurityService security, User user, Item item) {
return user != null && item != null && user.Id == item.AuthorId
&& security.Does(user).Have(MyPermission).On(item);
}
Run Code Online (Sandbox Code Playgroud)
我想要注意的是,如果任何项为null,则ISecurityService API当前返回false.但是它会进行数据库调用,因此这里的代码检查null然后执行id检查,因为在大多数情况下,这将返回false并避免数据库调用.
您可以定义一个隐藏null检查的计算构建器,但它不会为您提供非常方便的语法,因此我可能不会这样写.如果有一些更轻量级的语法,那将是很酷的,因为它会非常有用.此外,计算构建器只传播null,因此您将以类型的结果结束Nullable<bool>:
nullable { let! u = user
let! i = item
return u.Id == i.AuthorId && security.Does(user).Have(MyPermission).On(i) }
Run Code Online (Sandbox Code Playgroud)
我们的想法是,let!只有当参数不是时,操作才会调用其余的计算null.如果是null,它会立即返回null整体结果.
我认为你没有太多可以使代码更好.当然,如果它都是用F#编写的,那么这些值都不是null(因为F#声明的类型不允许该null值),但这是一个不同的故事.
F#中的另一种方法是声明仅在值不匹配时才匹配的活动模式null.这样做的好处是,您不会拥有任何可能null在代码中具有价值的变量,因此不存在使用错误变量并获得NullReferenceException以下内容的危险:
let shouldGrantPermission = function
| NotNull(security:ISecurityService), NotNull(user), NotNull(item) ->
security.Does(user).Have(MyPermission).On(item)
| _ -> true
Run Code Online (Sandbox Code Playgroud)
活动模式的声明是:
let (|NotNull|_|) a = if a <> null then Some(a) else None
Run Code Online (Sandbox Code Playgroud)
然而,即使这并不比你拥有的东西更直接.我想处理null价值观只是痛苦:-).Ian Griffiths的这篇文章有一些相关的想法,但同样,它们都没有真正解决问题.