张赐荣——一位视障程序员。
赐荣小站: www.prc.cx

張賜榮

张赐荣的技术博客

博客园 首页 新随笔 联系 订阅 管理

C# 使用 using 语句确保对象引用的外部资源被释放

问题

当一个对象的工作完成或者超出作用域时,您需要采用一种方式确保一些处理得到执行。

解决方法

使用 using 语句,代码片段如下所示。

using System;
using System.IO;
using(FileStream FS = new FileStream("Test.txt", FileMode.Create))
{
FS.WriteByte((byte)1);
FS.WriteByte((byte)2);
FS.WriteByte((byte)3);
{
SW.WriteLine("some text.");
}
}

代码讲解

using ()语句非常易于使用,并且可以避免编写多余代码的麻烦。如果解决方案中没有使用 using 语句,将会如下所示。

FileStream FS = new FileStream("Test.txt", FileMode.Create);
try
{
FS.WriteByte((byte) 1);
FS.WriteByte((byte) 2);
FS.WriteByte((byte) 3);
StreamWriter SW = new StreamWriter(FS);
try
{
SW.WriteLine("some text.");
}
finally
{
if(SW != null)
{
((IDisposable) SW).Dispose();
}
}
}
finally
{
if(FS != null)
{
((IDisposable) FS).Dispose();
}
}

关于 using 语句,需要注意以下几点。
• 存在一个 using 指令,如下所示。应将其与 using 语句区分开。这可能会使初次接触这一语言的开发人员混淆。
using System.IO;
• using 语句的子句中定义的变量都必须具有相同的类型,并且必须具有一个初始化器。不过,因为可以在单个代码块前使用多个 using 语句,所以这并不是一个重大的限制。
• using 子句中定义的变量在 using 语句体中被认为是只读的。这可以阻止开发人员在尝试处置变量最初引用的对象时无意中将变量转变成引用不同的对象,避免引发问题。
• 不应该在 using 块外声明变量,然后在 using 子句内初始化它。
下面的代码说明了最后一点。

FileStream FS;
using(FS = new FileStream("Test.txt", FileMode.Create))
{
FS.Writebyte((byte)1);
FS.Writebyte((byte)2);
FS.Writebyte((byte)3);
using(StreamWriter SW = new StreamWriter(FS))
{
SW.WriteLine("some text.");
}
}

对于这段示例代码来说,不会有任何问题。但是,要考虑到变量 FS 是可以在 using 块外使用的。实际上,可以将这段代码修改为下面这样。

FileStream FS;
using(FS = new FileStream("Test.txt", FileMode.Create)) 
{
	FS.Writebyte((byte)1);
	FS.Writebyte((byte)2);
	FS.Writebyte((byte)3);
	using(StreamWriter SW = new StreamWriter(FS)) 
	{
		SW.WriteLine("some text.");
	}
}
FS.Writebyte((byte)4);

这段代码可以编译,但会在这个代码段的最后一行上引发一个 ObjectDisposedException ,因为已经对 FS 对象调用了 Dispose 方法。对象此时还没有被垃圾回收,仍然以被处置过的状态存在于内存中。

参考

posted on 2022-05-29 08:23  张赐荣  阅读(113)  评论(0编辑  收藏  举报

感谢访问张赐荣的技术分享博客!
博客地址:https://cnblogs.com/netlog/
知乎主页:https://www.zhihu.com/people/tzujung-chang
个人网站:https://prc.cx/