繁体   English   中英

C#:IDisposable类需要'using'子句吗?

[英]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. 该对象将需要一会儿,但在当前代码块退出后将不再需要。
  2. 该对象将被提供给当前例程的调用者,由后者负责。
  3. 负责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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM