ここでBrian Warshawが述べたように、オブジェクトが確実に破棄されるようにするための単純な実装try
とブロックです。finally
彼の答えに加えて、 block は、 scopeを使用して内部に戻ったusing
場合でも、オブジェクトが確実に破棄されるようにします。
私はかつてこれに興味があり、次のアプローチを使用してテストしました。
カスタム IDisposable テスト クラスとメイン
private class DisposableTest : IDisposable
{
public string Name { get; set; }
public void Dispose() { Console.WriteLine("{0}.Dispose() is called !", Name); }
}
public static void Main(string[] args)
{
try
{
UsingReturnTest();
UsingExceptionTest();
}
catch { }
try
{
DisposeReturnTest();
DisposeExceptionTest();
}
catch { }
DisposeExtraTest();
Console.ReadLine();
}
テストケースの実装
private static string UsingReturnTest()
{
using (DisposableTest usingReturn = new DisposableTest() { Name = "UsingReturn" })
{
return usingReturn.Name;
}
}
private static void UsingExceptionTest()
{
using (DisposableTest usingException = new DisposableTest() { Name = "UsingException" })
{
int x = int.Parse("NaN");
}
}
private static string DisposeReturnTest()
{
DisposableTest disposeReturn = new DisposableTest() { Name = "DisposeReturn" };
return disposeReturn.Name;
disposeReturn.Dispose(); // # IDE Warning; Unreachable code detected
}
private static void DisposeExceptionTest()
{
DisposableTest disposeException = new DisposableTest() { Name = "DisposeException" };
int x = int.Parse("NaN");
disposeException.Dispose();
}
private static void DisposeExtraTest()
{
DisposableTest disposeExtra = null;
try
{
disposeExtra = new DisposableTest() { Name = "DisposeExtra" };
return;
}
catch { }
finally
{
if (disposeExtra != null) { disposeExtra.Dispose(); }
}
}
出力は次のとおりです。
- UsingReturn.Dispose() が呼び出されます!
- UsingException.Dispose() が呼び出されます!
- DisposeExtra.Dispose() が呼び出されます!