VB中的Closure:第1部分
[原文作者]:Jared Parsons
[原文链接]:Closures in VB: Part 1
我叫Jared Parsons,是微软VB 编译和调试组的软件开发人员。我为VB 9.0开发的一个新特性叫做“lexical closure支持”。这个特性是对VB语言的一个重要扩充,因此我将通过几篇博客来解释这一特性是如何影响你的代码。
LexicalClosures(通常被简称为Closures)是Visual Basic 9.0几个新特性的内在支持,是Lambda和查询表达式的内在实质。我将针对VB 9.0的Closures工作机制,局限性以及使用时易犯的错误将做系列性介绍。
首先,我们从一个基本的结论:什么是closure开始说起吧。在Wikipedia的定义是“...用于关联方法与环境的语法概念...”,但我更喜欢这样来描述它:一个Closure是一个特性,该特性允许用户从多个函数访问某一个环境(局部变量,参数和方法)。举例说明可能更易说明清楚:)
Class C1
Sub Test()
Dim x = 5
Dim f = Function(ByVal y As Integer) x + y
Dim result = f(42)
End Sub
End Class
在这段代码中,包含了一个Lambda表达式。它有一个方法参数并将这个参数与“Test”的局部变量做累加。在VB中,Lambda表达式被作为函数来实现的(C#也一样)。所以,现在我们有2个方法,它们是“Test”和“f”方法。“f“方法将访问“Test”方法的局部变量x。closure将在这里发挥其功效了。Closures负责使变量x在同一个进程中对于2个方法都可用(这被称为“提升变量”)。
要做到这点,编译器将执行4个步骤的操作:
1. 创建一个类,用于包含x以便在2个方法之间共享这个变量。这里,这个类称为“Closure”
2. 编译器将在这个“Closure”类中为Lambda表达式创建一个新方法。这里,这个方法名叫“f”。
3. 编译器将在“Test“方法内部创建一个该“Closure”类的实例
4. 在“Test“方法中,将所有对于x的访问都重新改写为访问Closure类的成员变量x.
Class Closure
Public x As Integer
Function f(ByVal y As Integer) As Integer
Return x + y
End Function
End Class
Class C1
Sub Test()
Dim c As New Closure()
c.x = 5
Dim f As Func(Of Integer, Integer) = AddressOf c.f
Dim result = f(42)
End Sub
End Class
现在,两个方法都可以共享变量x了。同时,用户也无需了解任何有关编译器实际产生的代码。你可以从这个简单例子中了解到closure和所有其它VB9.0新特性(类型推断,Lambda表达式)是如何为你节省代码量的了。
注意:这个例子只是模拟了当使用Closure时编译器所产生的代码,但是实际生成的代码却看起来不是这么“优雅”,反而还用了许多难以理解的名字,如“$Lambda_1”等。
下次,我将深入地阐述一些closure更多的使用(多变量,方法访问,术语等)。
Jared Parsons
Read the complete post at http://blog.joycode.com/vbcti/archive/2007/10/11/109287.aspx