从F#调用C#委托 - 是否有更清晰的语法?

时间:2015-02-04 10:24:41

标签: f# delegates syntactic-sugar

在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#中有更清晰的语法吗?

1 个答案:

答案 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#函数值。