クラスで定義しているプロパティのオブジェクトを、クラスのインスタンスがDispose()される際、一緒にDispose()させたい。
プロパティが少数であれば素直にプロパティを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()を試みる。…さらに入れ子の場合は?再帰処理?あまり良い方法では無さそうな感じが…
usingとdispose()が便利だったので作成してみましたが、配列やコレクションの場合どうしましよう?IEnumerableかチェックしてforeachが使えるようであれば、foreachで各要素に対しdispose()を試みる。…さらに入れ子の場合は?再帰処理?あまり良い方法では無さそうな感じが…
コメント