読者です 読者をやめる 読者になる 読者になる

プログラマーな日々

プログラマーをやっています。好きなツール:WorkFlowy、好きな言語:C#、好きなサービス:Backlog、好きなAWS:AWS Lambda。

保持しているリソースのDisposeを呼び出さないDataSetの問題に対処する

DataSetもTableAdapterと同様に保持しているリソースのDisposeを呼び出してくれません。

そこで、以下のTableAdapterのエントリーに続いて、ヘルパーメソッドを書いてみました。
保持しているリソースのDisposeを呼び出さないTableAdapterの問題に対処する - プログラマーな日々
TableAdapterって便利ですよね。でも大きな欠点が1つあります。それは内部で保持しているIDisposableを実装しているリソースのDisposeを呼び出さないことです。 そこで、その欠点に対処するヘルパーメソッドを書いてみました。 ...

DataSetを引数に指定できるので、TableAdapterよりも楽ですね。

using System.Data;
using SystemExtensions;

namespace Models {
    /// <summary>
    /// <see cref="System.Data.DataSet"/> をサポートする静的なメソッドを提供します。
    /// </summary>
    public static class DataSetHelper {
        /// <summary>
        /// 使用しているマネージ リソースを解放します。
        /// </summary>
        /// <param name="dataSet">マネージ リソースを解放する <see cref="System.Data.DataSet"/></param>
        /// <param name="disposing">マネージ リソースを解放する場合は true。</param>
        /// <remarks>
        /// 保持している <see cref="System.IDisposable"/><see cref="System.IDisposable.Dispose"/> を呼び出さない 
        /// <see cref="System.Data.DataSet"/> の不具合に対処します。
        /// </remarks>
        public static void Dispose(DataSet dataSet, bool disposing) {
            if(disposing) {
                foreach(DataTable t in dataSet.Tables) {
                    foreach(DataColumn c in t.Columns) {
                        c.NullSafeDispose();
                    }
                    t.NullSafeDispose();
                }
            }
        }
    }
}

NullsafeDisposeについてはこちらを参照してください。
拡張メソッドでNullセーフなメソッドを実装する - プログラマーな日々
オブジェクトのNullチェックって面倒ですよね。.Net 3.0以降なら拡張メソッドでNullセーフなメソッドを実装できます。 ...

こんな風に使用します。

namespace Models {
    public partial class HogeDataSet {
        /// <summary>
        /// 使用しているアンマネージ リソースを解放し、オプションでマネージ リソースも解放します。
        /// </summary>
        /// <param name="disposing">
        /// マネージ リソースとアンマネージ リソースの両方を解放する場合は true。
        /// アンマネージ リソースだけを解放する場合は false。
        /// </param>
        protected override void Dispose(bool disposing) {
            DataSetHelper.Dispose(this, disposing);
            base.Dispose(disposing);
        }
    }
}