hakeの日記

Windows環境でプログラミングの勉強をしています。

C# - usingブロックの動作

昨日使用したusingブロックの動作の確認。
MSのドキュメントによると、using( )内で宣言できるのは、IDisposableインターフェースを継承したクラスになる。具体的には、void Dispose() メソッドを持っていることが必要となる。
usingブロックを抜ける際に、このDispose() メソッドが実行される。

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

このメソッド内で終了処理およびインスタンス自身の破棄が実施される?ので、デストラクタは実行されない。
usingブロック外でnewによりインスタンスが生成された場合は通常どうりデストラクタが実行される。

using System;

//usingのテスト

class MyClass : IDisposable
{
    private bool disposed = false;

    public MyClass()
    {
        Console.WriteLine("MyClassコンストラクタ実行");
    }

    public void Dispose()
    {
        Console.WriteLine("Dispose実行");
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        Console.WriteLine("Dispose({0})実行", disposing);
        if(!this.disposed)
        {
            if(disposing)
            {
                Console.WriteLine("usingブロック終了時の処理");
            }
            else
            {
                Console.WriteLine("デストラクタ処理");
            }
            disposed = true;
        }
    }
    
    public void MyMethod()
    {
        Console.WriteLine("MyMethod()実行");
    }

    ~MyClass()
    {
        Dispose(false);
    }
}

class MyMain
{
    static void Main(string[] args)
    {
        using( var m1 = new MyClass() )
        {
            Console.WriteLine("usingブロック内実行開始");
            m1.MyMethod();
            Console.WriteLine("usingブロック内実行終了");
        }
        
        Console.WriteLine("-----");
        var m2 = new MyClass();
        m2.MyMethod();
    }
}

 

実行結果

MyClassコンストラクタ実行
usingブロック内実行開始
MyMethod()実行
usingブロック内実行終了
Dispose実行
Dispose(True)実行
usingブロック終了時の処理
-----
MyClassコンストラクタ実行
MyMethod()実行
Dispose(False)実行
デストラクタ処理