簡體   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