[英]C#: IDisposable classes need 'using' clause?
如果正在使用IDisposable
类,则应始终使用using
子句,例如:
using (MyClass myclass = new MyClass())
{
...
}
using
语句确保即使发生异常或对象超出范围,也将调用Dispose
以释放资源。
这比使用以下代码块更简单,
try
{
...
}
catch()
{
// Handle exception
}
finally
{
// Free resources by calling Dispose()
}
注意
如果不想处理exception
则不必使用catch
块。 在这种情况下, try
... finally
块就足够了(如其他答案所示)。
替代方式
您可以在同一using语句中创建多个一次性对象的实例,例如
using(MyClass myclass1 = new MyClass(),
MyClass myclass2 = new MyClass())
{
...
}
例
通过了解C#中的'using'语句
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
被( CLR )翻译为
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes!= null)
{
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}
}
您可以在示例开头指定的链接中查看生成的MSIL 。
更多信息
它使代码更具可读性。 因此,通常应在using块中声明并实例化该对象。 它确保即使发生异常也将调用Dispose方法。 在编译时,相同的表达式如下所示 :
{
MyClass myclass = new MyClass ();
try {
//Do something with myclass
}
finally {
if (myclass != null)
((IDisposable)myclass).Dispose();
}
}
using子句是以下代码块上的语法糖:
MyClass myclass = null;
try
{
myclass = new MyClass();
//do work
}
finally
{
if(myclass != null)
myclass.Dispose();
}
如果一个类实现IDisposable,则应确保在使用完Dispose后调用它。 using子句只是一种简单的方法。 因此,您不必使用“ using”来执行此操作,但应确保调用了它。
如果类实现IDisposable
,则在处理完对象后应始终调用Dispose
。 C#提供using语句作为语法糖,以使其变得更容易。 因此,不需要使用using
来调用Dispose
。 就是说,这是调用Dispose
事实上的标准方法。 即,如果您的代码未使用using
而是在finally块中调用Dispose
,那么对于有经验的编码人员而言,这看起来有些奇怪。
using块的扩展(假设MyClass是引用类型)为:
{
MyClass myclass = new MyClass();
try {
//...
}
finally {
if (myclass != null) ((IDisposable)myclass).Dispose();
}
}
using
版本更易于编码和阅读。
简而言之,如果它实现了IDisposable,并且您想调用该方法(在执行操作时,也会在finally块中的异常上进行调用。请使用using。
GC不会为您调用Dispose()! 一些类实现了终结器〜ClassName(),但要避免这种情况,因为它有很多副作用并且不明显。
您可以将using语句读取为:
TestClass test = new TestClass();
try
{
test.DoSomething();
}
finally
{
test.Dispose();
}
只要对象的生存期足够短,就应该始终这样做。 有时,您必须单独处理清理,因为您的对象的生命周期很长,并且在代码块完成之后会持续很长时间。
创建IDisposable对象的情况有以下三种:
在场景1中,使用“ using”块创建对象; 它的清理将被自动处理。
在场景2中,使用带有“ ok”变量的“ try-finally”块,该变量最初设置为“ False”,但在“ try”结束时或返回任何值之前设置为“ True”。 最后,如果“ oK”为假,则调用Dispose以确保清理部分构造的对象。
在方案3中,将对象在创建后立即存储在字段中,并定义一个IDisposable.Dispose方法,该方法会将字段中的值复制到变量中,使该字段为空,如果该变量为非null,处理它(如果有多个线程同时调用Dispose的可能性,请使用Interlocked.Exchange锁存并清除该字段)。 构造器也应该受到保护,就像方案2中的功能一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.