9.5.1 处理记录和成员

728 篇文章 1 订阅
349 篇文章 0 订阅

9.5.1 处理记录和成员

 

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

 

清单 9.20 把 F# 类型编译成库(F#)

 

namespace Chapter09.FSharpExport    [1]

open System

open System.Drawing

 

type Rect =

  { Left : float32; Width : float32    | [2]

    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) }  |  [3]

  member x.ToRectangleF () =                            |

    RectangleF(x.Left,x.Top, x.Width, x.Height)               |

 

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

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

 

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

 

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

 

清单 9.21 使用F# 库中的类型 (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);  [1]

    var rc2 =rc1.Deflate(20.0f, 10.0f);     [2]

   Console.WriteLine("({0}, {1}) - ({2}, {3})",

      rc2.Left,rc2.Top, rc2.Width, rc2.Height);

  }

}

 

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

 

注意

 

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

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值