您的位置:首页 > 其它

9.3.2 用 IDisposable 接口清理资源

2014-12-11 15:02 225 查看
9.3.2 用 IDisposable 接口清理资源

我们已经使用过几种实现了 IDisposable 接口的类型,比如,Graphics 和 SolidBrush。我们想使代码尽可能易于理解,因此,当使用完对象时,我们就显式调用 Dispose 方法。

C# 中包含了语法糖,以 using 语句的形式,保证了即使语句体内抛出异常,也能调用 Dispose;F# 有相似的结构,用 use 关键字。清单 9.11 是一个处理文件的简单示例。

Listing 9.11 使用 use 关键字处理文件 (F#Interactive)

> open System.IO;;

> let readFile() =

use reader = newStreamReader("C:\\test.txt") [1]

let text =reader.ReadToEnd()

Console.Write(text)

;; [2]

val readFile : unit –> unit

> readFile();; | 输出样本文件的内容

Hello world! |

Ahoj svete! |

创建 StreamReader(实现了 IDisposable 接口),我们使用 use 关键字声明[1]。注意,这个语法类似于通常 let 中使用的 let 关键字;所不同的是,F# 编译器会在函数的结尾[2],自动添加对 Dispose 方法的调用,因此,在我们处理完 StreamReader 之后,它会自动释放。编译器还插入一个 try - finally 块,以确保即使在发生异常时,也能进行清理。

C# 中的 using 结构和 F# 中的 use 关键字之间的重要区别,是在C# 中,必须明确地使用大括号指定 using 的作用域;而在 F# 中,Dispose 方法是在值可见的作用域结束时,被调用,通常这就是我们所需要的,因此,写许多代码就变得很容易了。清单 9.12 展示了 C# 和 F# 的版本。

清单 9.12 在 F# 和 C# 中清理资源

// F# version

let test() =

use reader = newStreamReader("C:\\test.txt")

let text = reader.ReadToEnd()

Console.Write(text) [1]

// C# version

void Test() {

using(var reader = newStreamReader("C:\\test.txt")) {

var text =reader.ReadToEnd();

Console.Write(text);

} [2]

}

在两种语言中,对象都是在运行到离开 reader 值可以访问的作用域时[1][2],被释放的。在 F# 中,默认是在函数结束时发生,这通常就是我们所需要的。当函数的代码需要连续运行很长时间时,它更好地保证了资源尽早释放。让我来说,是想关闭该文件,在关闭后,再输出内容到控制台。在 C# 中,我们必须在函数内部创建一个局部变量,并在 using 块内给它赋值;在 F# 中,可以更容易做到,因为,我们可以使用缩进指定作用域:

let test() =

let text =

use reader = newStreamReader("C:\\test.txt")

reader.ReadToEnd()

Console.Write(text)

这个语法可能有些出人意料,但是,一旦我们理解了,在 F# 中,每一个代码块就是一个表达式,它就变得清晰了。在前面的代码中,我们指定构造这个表达式的方式,与我们写 (1+2)*3,而不是默认的1+(2*3) 的方式,是相同的。这样,我们可以限制值 reader 的作用域到初始化值 text 的表达式。

虽然 use 关键字主要用于处理持有一些资源 .NET 对象,但是,它使用范围很广泛。让我们来看一个例子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: