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 对象,但是,它使用范围很广泛。让我们来看一个例子。
我们已经使用过几种实现了 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 对象,但是,它使用范围很广泛。让我们来看一个例子。
相关文章推荐
- 用IDisposable接口释放.NET资源
- 实现IDisposable接口,手动完成资源回收
- 手动实现IDisposable接口完成资源回收
- 建议46:显式释放资源需继承接口IDisposable
- 正确实现 IDisposable接口,释放托管或非托管资源
- C#资源回收和IDisposable接口的使用
- 编写高质量代码改善C#程序的157个建议——建议46:显式释放资源需继承接口IDisposable
- 用IDisposable接口释放.NET资源
- IDisposable资源释放接口
- 实现 IDisposable 接口的好处
- Spring学习----------资源访问接口Resource
- Spring Resource接口进行资源访问
- 通过Spring Resource接口获取资源
- 清理 iOS 项目不用的图片资源
- C#正确实现IDisposable接口
- 【python】研究与实践 python线程池爬取某网的接口视频资源入库
- Android Studio清理多余的资源文件
- 一个实现了 IDisposable 接口的基类
- 实现IDisposable接口的模式
- 如何编写提供了IDisposable接口的类.