C#:IDisposable类需要';使用';条款

C#:IDisposable类需要';使用';条款,c#,idisposable,using,C#,Idisposable,Using,如果我使用的是IDisposable类,我是否应该始终使用using子句,例如: using (MyClass myclass = new MyClass()) { ... } using语句确保调用Dispose以释放资源,即使发生异常或对象超出范围 这比使用以下代码块更简单 try { ... } catch() { // Handle exception } finally { // Free resources by calling Dispose() } 注 如

如果我使用的是
IDisposable
类,我是否应该始终使用
using
子句,例如:

using (MyClass myclass = new MyClass())
{
...
}

using
语句确保调用
Dispose
以释放资源,即使发生异常或对象超出范围

这比使用以下代码块更简单

try
{
   ...
}
catch()
{
   // Handle exception
}
finally
{
    // Free resources by calling Dispose()
}

如果不想处理
异常
,则不需要使用
catch
块。在这种情况下,一个
try
最后一个
块就足够了(如其他答案所指出的)


替代方法
例如,可以在同一using语句中创建一次性对象的多个实例

using(MyClass myclass1 = new MyClass(), 
      MyClass myclass2 = new MyClass())
{
    ...
}

示例

被转换为(由)

您可以查看在示例开头指定的链接中生成的


更多信息

  • 相关的:

using子句位于以下代码块上:

MyClass myclass = null;
try
{
     myclass = new MyClass();
     //do work
}
finally
{
     if(myclass != null)
          myclass.Dispose();
}

如果类实现了IDisposable,则应确保在使用完Dispose后调用该类。using子句只是一种简单的方法。因此,您不必使用“using”来执行此操作,但您应该确保调用了它。

它使代码更具可读性。因此,作为一项规则,您应该在using块中声明并实例化对象。它确保即使发生异常,也会调用Dispose方法。在编译时,相同的表达式看起来类似于:


如果类实现了
IDisposable
,则在处理完对象后,应始终调用
Dispose
。C#提供了using语句作为语法糖,使之更简单。因此,不需要使用
using
调用
Dispose
。也就是说,这是调用
Dispose
的事实上的标准方式。i、 e.如果您的代码没有使用
using
,而是在finally块中调用
Dispose
,那么对于有经验的程序员来说,这看起来有点奇怪

using块的扩展(假设MyClass是引用类型)为:


使用
版本的
更易于编码和阅读。

简单地说,如果它实现了IDisposable,并且您希望调用该方法(在执行此操作时,也在finally块中的异常情况下)。请使用

GC不会为您调用Dispose()!有些类实现了finalizer~ClassName(),但请尽量避免这种情况,因为它有许多副作用,而且不明显

您可以通过以下方式阅读using语句:

TestClass test = new TestClass();
try
{
      test.DoSomething();
}
finally
{
      test.Dispose();
}

只要对象的生命周期足够短,您就应该始终这样做。有时您必须单独处理清理,因为您有生命周期很长的对象,这些对象在代码块完成后会持续很长时间。

创建IDisposable对象时有三种情况:

  • 该对象将需要一段时间,但在当前代码块退出后将不再需要。
  • 对象将被提供给当前例程的调用者,然后由调用者负责。
  • 负责IDisposable对象的类将其存储在字段中,以便在将来的方法/属性调用中使用。 在场景#1中,使用“使用”块创建对象;其清理将自动处理

    在场景#2中,使用一个“try finally”块和一个“ok”变量,该变量最初设置为“False”,但在“try”结尾或任何返回之前设置为“True”;在finally中,如果“ok”为False,则调用Dispose以确保清除部分构造的对象


    在场景#3中,创建对象后立即将其存储在字段中,并定义一个IDisposable.Dispose方法,该方法将字段中的值复制到变量中,将字段清空,如果该变量不为null,则将其销毁(如果可能有多个线程同时调用Dispose,请使用Interlocked.Exchange锁定并清除该字段).Constructor也应该像场景2中的函数一样受到保护。

    如果没有
    catch
    块,如何处理异常?@Craig Johnston,
    catch
    块不是必需的。一个
    试试
    如果不想处理
    异常,最后
    块就足够了。哇,我刚刚看到了一个所有其他更好的答案,很抱歉添加以下内容:(
    
    MyClass myclass = null;
    try
    {
         myclass = new MyClass();
         //do work
    }
    finally
    {
         if(myclass != null)
              myclass.Dispose();
    }
    
    {
      MyClass myclass = new MyClass ();
      try {
        //Do something with myclass
      }
      finally {
        if (myclass != null)
          ((IDisposable)myclass).Dispose();
      }
    }
    
    {
        MyClass myclass = new MyClass();
        try {
            //...
        }
        finally {
            if (myclass != null) ((IDisposable)myclass).Dispose();
        }
    }
    
    TestClass test = new TestClass();
    try
    {
          test.DoSomething();
    }
    finally
    {
          test.Dispose();
    }