160 likes | 243 Views
IDisposable を成敗する. guicheng. IDisposable オブジェクトは、使用したら確実に Dispose() しなければならない。 Dispose() し忘れるとメモリリークやゾンビプロセスが発生する。 例外の考慮も 必要。 特に、 COM ベース のライブラリを使用する場合は注意が必要。 Excel LDAP などなど. んじゃ、どう やって IDisposable オブジェクトを成敗するか。. 1. 普通に Dispose(). Dispose01 disp_obj = new Dispose01 ();
E N D
IDisposable を成敗する guicheng
IDisposable オブジェクトは、使用したら確実にDispose() しなければならない。 • Dispose() し忘れるとメモリリークやゾンビプロセスが発生する。 • 例外の考慮も必要。 • 特に、COMベースのライブラリを使用する場合は注意が必要。 • Excel • LDAP • などなど
んじゃ、どうやってIDisposable オブジェクトを成敗するか。
1. 普通に Dispose() Dispose01 disp_obj = newDispose01(); Console.WriteLine( "何か処理" ); disp_obj.Dispose();
1. 普通に Dispose() • 利点 • 簡潔明瞭。誰でもわかる。 • 欠点 • 例外が発生するとDispose()されない。 • Dispose()を書き忘れる場合がある。 • 変数が増えるととんでもないことになる。
2. try-catch 構文を使う Dispose01 disp_obj = null; try{ disp_obj = newDispose01(); Console.WriteLine( "何か処理" ); }catch{ Console.WriteLine( "例外処理" ); }finally{ if( disp_obj != null ){ disp_obj.Dispose(); } }
2. try-catch 構文を使う • 利点 • 例外が発生しても確実にDispose()を駆動できる。 • 欠点 • ネストすると大変なことになる • Excel を扱おうと思うとえらいことに……
2. try-catch 構文を使う Dispose01 disp_obj01 = null; try{ disp_obj01 = newDispose01(); Dispose02 disp_obj02 = null; try{ disp_obj02 = disp_obj01.GetChiled(); }finally{ if( disp_obj02 != null ){ disp_obj02.Dispose(); } } }finally{ if( disp_obj01 != null ){ disp_obj01.Dispose(); } }
3. using 構文を使う try{ using( Dispose01 disp_obj = newDispose01() ) { Console.WriteLine( "何か処理"); } }catch{ Console.WriteLine( "例外処理" ); }
3. using 構文を使う • 利点 • 確実にDispose()できる • タイプ量が少ない • 欠点 • using()内で例外が発生すると dispose() が駆動しない • ネストが深くなる問題は変わらない
3. using 構文を使う try{ using( Dispose01 disp_obj01 = newDispose01() ){ using( Dispose02 disp_obj02 = disp_obj01.GetChiled() ){ using( Dispose03 disp_obj02 = disp_obj02.GetChiled() ){ Console.WriteLine( "何か処理" ); } } } }catch{ Console.WriteLine( "例外処理" ); }
4. Stack を使う Stack<IDisposable> disp_stack = newStack<IDisposable>(); try{ Dispose01 disp_obj = newDispose01(); disp_stack.Push( disp_obj ); Console.WriteLine( "何か処理" ); }finally{ foreach( IDisposable stack_elem in disp_stack ){ stack_elem.Dispose(); } }
4. Stack を使う • 利点 • 例外が発生しても確実にDispose()できる。 • 先入れ後出しで処理できる。 • ネストが深くならない。 • 欠点 • 生成したオブジェクトをスタックに Push() しなければならない。 • あとでDispose()することと比較したら利便性は高い。
4. Stack を使う Stack<IDisposable> disp_stack = newStack<IDisposable>(); try{ Dispose01 disp_obj01 = newDispose01(); disp_stack.Push( disp_obj01 ); Dispose02 disp_obj02 = disp_obj01.GetChiled(); disp_stack.Push( disp_obj02 ); Dispose03 disp_obj03 = disp_obj02.GetChiled(); disp_stack.Push( disp_obj03 ); Console.WriteLine( "何か処理" ); }finally{ foreach( IDisposable stack_elem in disp_stack ){ stack_elem.Dispose(); } }
まとめ • COMライブラリを扱うには、生成した IDispose オブジェクトをいかに成敗するかがキモ。 • 例外が発生した場合もきちんと処理しなければならない。 • Stackを使うとすげー便利
告知 • Stackモデルを発展させるといっぱしのフレームワークになる。 • このフレームワークを使うとC#からレイトバインドでExcelを叩けるようになる。 • わんくま名古屋#19(2011/10/29)でExcel制御フレームワークについて発表します!