F #powerpack附带了一组转换方法,可以从Func <...>转换为F#函数,无论是标准函数还是Tuple函数.但是有可能实现相反的目的:如果你想从F#代码调用一个C#方法,它接受Func <...>并想使用原生的F#lambda表达式(例如fun x - > some_function_of(x))?
如果我将带有签名'a - >'b的F#函数发送到期望Func的C#方法,那么F#编译器会生成以下错误:
This expression was expected to have type Function<'T,'R> but here has type 'T -> 'R
我想继续使用F#lambda表达式,但要使用转换层,以便能够将它们作为C#Func lambda发送.这可以实现吗?
这有效:
type MyType () =
static member MyFn (fn : Func<bool>) = fn.Invoke ()
MyType.MyFn (fun _ -> false)
Run Code Online (Sandbox Code Playgroud)
这不(错误FS0002):
let myFn (fn : Func<bool>) = fn.Invoke ()
myFn (fun _ -> false)
Run Code Online (Sandbox Code Playgroud)
这也不是(错误FS0002):
type MyDU = Fn of Func<bool>
Fn (fun _ -> false)
Run Code Online (Sandbox Code Playgroud)
这种相当恼人的不一致的原因是什么?
这不是关于Windows窗体,它只是针对"背景".
当我遇到AddRange
一个MenuStrip.Items
需要ToolStripMenuItem
投入的错误时,我正在玩Windows FormsToolStripItem
但是我已经有AddRange
一个Form.Controls
之前并不要求强制转换.
经过一些实验后,我设法发现当有多个重载时发生错误,AddRange
所以我试图验证我的想法:
type Foo () = class end
type Bar () = inherit Foo ()
type FooCollection () = class end // not really necessary
type Test1 () =
member __.AddRange (col: FooCollection) = () // could be an int or anything instead
member __.AddRange (foos: Foo []) = ()
type Test2 () = member __.AddRange (foos: Foo []) = ()
let lst1, lst2 …
Run Code Online (Sandbox Code Playgroud) 为什么...
type IntDelegate = delegate of int -> unit
type ListHelper =
static member ApplyDelegate (l : int list) (d : IntDelegate) =
l |> List.iter (fun x -> d.Invoke x)
ListHelper.ApplyDelegate [1..10] (fun x -> printfn "%d" x)
Run Code Online (Sandbox Code Playgroud)
不编译,时间:
type IntDelegate = delegate of int -> unit
type ListHelper =
static member ApplyDelegate (l : int list, d : IntDelegate) =
l |> List.iter (fun x -> d.Invoke x)
ListHelper.ApplyDelegate ([1..10], (fun x -> printfn "%d" x))
Run Code Online (Sandbox Code Playgroud)
呢?
唯一的区别在于,在第二个中, …