Fra*_*cal 6 f# functional-programming
我想知道以功能方式与F#中的C#代码交互的最佳方式,当我必须多次检查null时.
从C#开始,很简单,因为我有空操作符
public bool Authorize(DashboardContext dashboardContext)
{
var context = new OwinContext(dashboardContext.GetOwinEnvironment());
var user = context.Authentication.User;
return user?.Identity?.IsAuthenticated ?? false;
}
Run Code Online (Sandbox Code Playgroud)
从F#开始,我做到了这一点
let authorize (ctx:DashboardContext) =
match OwinContext(ctx.GetOwinEnvironment()) with
| null -> false
| c -> match c.Authentication.User with
| null -> false
| user -> user.Identity.IsAuthenticated
Run Code Online (Sandbox Code Playgroud)
但我对此并不满意.这样做的功能方法是什么?我想也许一些计算表达式会有所帮助,但我不知道如何完成.
Option.ofObj将可空对象转换为Option.然后,您可以使用Option模块中已定义的帮助程序.例如,您在那里编写的部分模式已经封装了Option.bind.
let authorize (ctx:DashboardContext) =
ctx.GetOwinEnvironment() |> OwinContext |> Option.ofObj
|> Option.bind (fun c -> c.Authentication.User |> Option.ofObj)
|> Option.map (fun user -> user.Identity.IsAuthenticated)
|> Option.defaultValue false
Run Code Online (Sandbox Code Playgroud)
Option.bind取一个Option<'a>和一个接受类型的函数'a并返回一个Option<'a>.当它在管道中使用时,它是一种"映射" Some或过滤掉它的方式None.
我会说你写的函数实际上看起来很好,但是这种方式可能被认为是更惯用的,尽管在这个例子中可以说有点难以理解.Option.bind当它保存多个嵌套级别时真正发挥作用.
值得注意的是,在你的F#函数和我的函数中,我们假设Authentication和Identity属性的非null ,并且在访问它们的属性时冒着空引用异常的风险.这与使用空传播的C#方法形成对比.目前在F#中没有内置方法可以做到这一点,但可能有一些先进的方法来模拟它.
也可以使用计算表达式来完成此操作.看到MaybeBuilder 这里.