[英]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.