在C#中,如果委托定义如下:
delegate void A();
A a = () => {Console.WriteLine("Test")};
可以使用:
调用它a.Invoke(); // Works
a(); // Also works
在F#中,可以调用C#委托:
a.Invoke() // Works fine.
a() // Error: This value is not a function and cannot be applied
为什么我不能在F#中使用第二种方法?在C#中,()运算符是否只是映射到Invoke方法,或者是否在其下发生了其他事情。 F#中有更清晰的语法吗?
答案 0 :(得分:7)
我认为你无能为力。 F#和C#使用不同的类型来表示可以调用的内容。在C#中,使用的自然是委托(如Func<T1, T2>
),在F#中,使用的自然是F#函数值(T1 -> T2
)。从F#调用委托更加丑陋,就像从C#调用F#函数一样丑陋。
最好的办法是在大多数时间使用本机表示,并在边界处将代理转换为函数(反之亦然)。
因此,在编写F#代码时,我只会使用函数:
let foo f = f(10) + f(32)
但是当把它暴露给C#时,我会编写一个接受委托并在调用foo
之前将其转换为函数的操作:
type CSharpFriendly() =
static member Foo(f:Func<int, int>) = foo f.Invoke
这也使用了这样一个事实:只写f.Invoke
会返回一个不错的F#函数值。