【C#】クラスのプロパティがIDisposableの派生オブジェクトを全てDispose()する。

C# コンピュータ
C#
クラスで定義しているプロパティのオブジェクトを、クラスのインスタンスがDispose()される際、一緒にDispose()させたい。
プロパティが少数であれば素直にプロパティをDispose()すればよいのですが、プロパティが多数の場合、プロパティが異なるだけのDispose()の呼び出しが多量に発生するので、シンプルに処理する方法を考えてみました。

プロジェクトの作成

PowerShellで実行。要dotnet.exe

mkdir プロジェクト名
cd プロジェクト名
dotnet new console
code .

ソースコード

ファイル名:Program.cs

using System;

namespace DisposeTest
{
    class DisposableClass : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("DisposableClass.Dispose()");
        }
    }
    class AutoDisposeClass : IDisposable
    {
        public DisposableClass obj { get; set; } = new();
        public DisposableClass obj2 { get; set; } = new();

        public void Dispose()
        {
            Console.WriteLine("AutoDisposeClass.Dispose()");
            foreach (var o in this.GetType().GetProperties())
            {
                if (o.GetValue(this) is IDisposable)
                {
                    var oo = (IDisposable)o.GetValue(this);
                    oo.Dispose();
                }
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            using(var obj3 = new AutoDisposeClass()){}
            // AutoDisposeClass.Dispose()
            // DisposableClass.Dispose()
            // DisposableClass.Dispose()
        }
    }
}

実行

dotnet run

AutoDisposeClass のインスタンスobj3がusingを抜ける際Dispose()されてると、obj3のプロパティ(obj, obj2)のDispose()が呼び出されています。

コード内で特定のプロパティを指定してDispose()しているのではなく、GetProperties()でプロパティの一覧を取得してIDisposableにキャストできるオブジェクトを順次Dispose()しています。
ですのでプロパティが増えてもDispose()してくれるはずです。

追記:
usingとdispose()が便利だったので作成してみましたが、配列やコレクションの場合どうしましよう?IEnumerableかチェックしてforeachが使えるようであれば、foreachで各要素に対しdispose()を試みる。…さらに入れ子の場合は?再帰処理?あまり良い方法では無さそうな感じが…

コメント