像 C# 一样,F# 也是一种静态类型的语言,就是说,编译器知道每个值的类型,以及类方法和属性的签名。对于与 C# 的互操作性来说,这是非常重要的,因为,编译器可以生成代码,看起来就像普通的 .NET 库。
与其他 .NET 语言的互操作性
F# 和 C# 或 VB.NET 之间的互操作性是非常平滑的,相比有 .NET 实现的动态类型的语言,比如 Python、Ruby、JavaScript。这些语言的编译器不知道方法所要求的参数类型,是 int,还是比如Customer,因此,使用 C# 3.0 时,要利用这些语言写的代码是比较困难的。通常,甚至不知道对象是否包含具有特定名字的方法,所以,C# 代码看应该像这样:
obj.InvokeMethod("SayHello", newobject[] { "Tomas" });
这个例子指定方法的名字为一个字符串,并以数组的方式传递参数值给方法。对于许多语言来说,这是一个重要的问题,所以,C# 4.0 引入了动态类型,它允许这样写:
obj.SayHello("Tomas");
obj.SaiHello("Tomas");
这个语法与正常的方法调用相同,但有一个重要的区别。我们还添加另一个方法调用,但故意用了一个不存在的方法名。这将正确编译,因为方法的名字在内部表示成字符串,就像在前面的例子一样。问题要到运行时间才会发现。F# 是静态类型的事实说明,我们不必担心出现这种情况:我们可以依靠编译器发现类似的错误,在调用到其他 C# 代码时。
当创建要在 C# 中使用的 F# 库,我们需要区分两种 F# 构造。第一种包括带成员的类或记录,它就是以标准的 C# 类出现的,使用起来没有任何麻烦;第二种包括值或高阶函数,以非标准方式编译,很难在 C# 中使用。我们先看一个第一种情况的例子。