9.5.1 处理记录和成员

9.5.1 处理记录和成员


    我们先从一个基本的例子开始。在本章的第一节中,我们看到如何添加成员到表示矩形的 Rect 的类型。现在,我们要从 C# 中使用这个类型。首先,我们需要创建一个新的 F# 的库项目,添加源文件(例如,export.fs),代码在清单 9.20。

 

Listing 9.20 Compiling F# types into a library (F#)

 

namespace Chapter09.FSharpExport

open System
open System.Drawing

type Rect =
  { Left : float32; Width : float32
    Top : float32; Height : float32 }

  member x.Deflate(wspace, hspace) =
    { Top = x.Top + wspace; Height = x.Height - (2.0f * hspace)
       Left = x.Left + hspace; Width = x.Width - (2.0f * wspace) }
  member x.ToRectangleF () =
    RectangleF(x.Left, x.Top, x.Width, x.Height)

 

    正如你可以看到,我们已经添加了一行指定 .NET 命名空间。这个命名空间会包含所有这个文件中的类型声明(在本例中,只有一个类型,Rect)。这个类型将很容易从 C# 中使用,因为,记录的字段将成为属性和成员,出现在方法中。

    下一步,我们要添加一个新的 C# 项目到这个解决方案。添加对这个 F# 项目的引用,做法与引用另一个 C# 类库完全相同,但是,你还应该添加对 FSharp.Core.dll 程序集的引用。这是一个 F# 可再发行库,它包含了 F# 核心函数和类型。在配置项目之后,你看到的应该类似图 9.3。该图还显示了来自本章的其他 F# 类型,出现在 C# 的智能感知中。

image

图 9.3 添加对这个 F# 库的引用后,我们可以在智能感知中看到这个 F# 库中的类型。F# 记录类型 Rect 被编译为一个普通的类。

 

    如果你使用过智能感知,会看到 F# 类型出现的命名空间,是我们在源代码中指定的。智能感知还显示这个类型有哪些属性和方法,所以,你在不需要进一步帮助的情况下,就一定能够使用它了。出于完整性,清单 9.21 给出了一个例子。

 

Listing 9.21 Using types from the F# library (C#)

 

using System;
using Chapter09.FSharpExport;

class Program {
  static void Main(string[] args) {
    var rc1 = new Rect(0.0f, 100.0f, 0.0f, 50.0f);
    var rc2 = rc1.Deflate(20.0f, 10.0f);
    Console.WriteLine("({0}, {1}) - ({2}, {3})",
      rc2.Left, rc2.Top, rc2.Width, rc2.Height);
  }
}

 

    清单 9.21 的代码首先创建 Rect 类型的一个实例。它使用的构造函数,是由 F# 编译器自动生成的,对应于创建记录的 F# 代码。我们必须在构造记录时,指定所有字段的值,以后就不能改变,因为类型是不可变的。下一步是调用Deflate方法,一个非常普通的方法,虽然它
是以纯函数风格实现的,所以,它返回一个新的 Rect 值,而不是改变现有的值。最后,我们打印返回矩形的有关信息。这也是容易的,因为记录字段暴露为 .NET 属性。

 

注意

 

    我们已经看到从 C# 中在引用 F# 的项目,因为这是一种常见的情况,我们想明确地显示两种语言如何很好地一起玩,当 F# 代码使用对象类型时。你也能从 F# 的应用程序中引用 F# 库。步骤是相同的:为这个 F# 库指定命名空间,在 Visual Studio 中添加一个引用,并在 F# 应用程序中添加适当的 open 指令。值得注意的是,当从 F# 中引用 F# 库时,编译器将认可这个库是在F#中创建的,所有构造(如差别联合或函数)都可以正常的 F# 方式访问。

 

    从 C# 中使用 Rect 类型是相当简单的,图 9.3 显示了来自本章的其他类型。F# 的接口声明(ClientTest)显示为一个普通的 .NET 接口,因此,互操作非常平滑。如果我们想导出高阶函数或值呢?这两个结构在 C# 中会是什么样子呢?

你可能感兴趣的:(职场,休闲,成员,处理记录)