我们有一个函数,可将Int32.TryParse
之类的内容从使用byref转换为使用Option作为返回值。
let inline ToOptionFunc refFunction x =
match refFunction x with
| true, value -> Some value
| false, _ -> None
像这样的东西由于对TryParse的新重载而停止在.NET Core中编译:
let Int32TryParse (x:string) =
ToOptionFunc Int32.TryParse x // A unique overload for method 'TryParse' could not be determined (...)
我尝试了很多事情,却通过这样写来使它不起作用:
let Int32TryParse (x:string) =
x |> ToOptionFunc Int32.TryParse
我只是不明白为什么会编译而前者不会编译。
答案 0 :(得分:11)
在.NET Core中,Int32.TryParse
函数有一些额外的重载-它可以解析string
或ReadOnlySpan<char>
。原始代码停止工作,因为编译器不知道您要使用哪个重载。
在不带管道的版本中,编译器需要对ToOptionFunc Int32.TryParse x
进行类型检查。它从左到右进行处理,到达Int32.TryParse
时,它还不知道x
(其类型注释将其约束到string
),并且不知道{{1 }},它不知道您需要哪个x
。
在带有管道的版本中,编译器需要对TryParse
进行类型检查。它从左到右进行操作,并且知道x |> ToOptionFunc Int32.TryParse
是x
,因此它推断传递给string
的函数也必须使用ToOptionFunc
-并且在检查{ {1}},它已经可以唯一地确定过载。
总结是,管道具有非常好的引导类型检查的属性!