C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Disposeメソッドを付けないクラスの開放について

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■96711 / inTopicNo.1)  Disposeメソッドを付けないクラスの開放について
  
□投稿者/ ルーキー (1回)-(2021/01/14(Thu) 13:29:26)

分類:[.NET 全般] 

C#(VS2019使用)を勉強し始めて間もないものです。
リソースの破棄でどうするのが良いのか不明なのでご教授ください。

ユーザークラス作成時、特に解放する必要が無いメンバーだけのクラスの場合、
破棄処理はどのようにするのが良いのでしょうか?

極端な例として、変数 string a = ""; のみ保持しているクラス(A)の場合、Disposeメソッドに何も記載することが無いかと思います。
そういったクラスでも空のDisposeメソッドを付加し、Usingで利用するのが良いのか、Dispseも不要で、
特に解放自体意識しなくて良いのかが良くわかっていません。

ちなみに下記の様に記述するとfinallyのnull代入部分のみ不要なので削除すべきのヒントが表示されます。
そもそもこのようなクラスの場合、Disposeやnull代入などせずにGC任せで良いのでしょうか?

var a = new A();

try
{
    a = null; → ここは「冗長なので削除」のヒント表示無し
}
catch (Exception ex)
{
    throw ex;
}
finally
{
    a = null; → 「冗長なので削除」のヒント表示
}

引用返信 編集キー/
■96713 / inTopicNo.2)  Re[1]: Disposeメソッドを付けないクラスの開放について
□投稿者/ 774RR (857回)-(2021/01/14(Thu) 13:51:50)
Dispose() つか IDisposable が必要なのはマネージメモリ以外のリソースを使っている場合で、例えば
ファイルハンドルとかネットワークソケットとかアンマネージメモリとかウィンドウリソースとか

ファイルが開かれたままでいつ Close() されるかわからないってのは UX 的に×なので
そういうときは「ここで Close() 」をするために Dispose() を使うと良いってこと。

例示 A の場合 Dispose() を書く必要はないっス。すべて GC にお任せ。
try / catch もいらないし null 代入もいらないです。っていうか「書くな」
そういうことにプログラマが煩わされないための gc システムなので。

Dispose() が必要、かつ try / catch / finally が必要ってことになったら、まずは using を検討

引用返信 編集キー/
■96714 / inTopicNo.3)  Re[1]: Disposeメソッドを付けないクラスの開放について
□投稿者/ WebSurfer (2181回)-(2021/01/14(Thu) 13:55:16)
No96711 (ルーキー さん) に返信

> 極端な例として、変数 string a = ""; のみ保持しているクラス(A)の場合、Disposeメソッドに何も記載することが無いかと思います。
> そういったクラスでも空のDisposeメソッドを付加し、Usingで利用するのが良いのか、Dispseも不要で、
> 特に解放自体意識しなくて良いのかが良くわかっていません。

そういう場合は Dospose 不用です。ガベージコレクタに任せて
おけば良いです。

Dispose を実装する必要があるのはアンマネージドリソースを
保持するクラスだけです。
引用返信 編集キー/
■96716 / inTopicNo.4)  Re[1]: Disposeメソッドを付けないクラスの開放について
□投稿者/ WebSurfer (2182回)-(2021/01/14(Thu) 14:47:28)
No96711 (ルーキー さん) に返信

ちなみに、アンマネージドリソースを保持しているクラスで Dispose する必要がある場合は、
Dispose パターンというのがあるのでそれに従って実装します。

それについては、Microsoft のドキュメント「Dispose メソッドの実装」などに書かれていま
す。

Dispose メソッドの実装
https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/implementing-dispose

・・・が、正直、自分は読んでもよく分かりませんでした。

Visual Studio には Dispose パターンに準拠したコードの骨組みを自動生成する機能が追加
されています。(VS2015 以降のはず) それをベースに自分で実装してみると理解が進むと
思いますので試してみてください。詳しくは以下の記事を見てください。

Dispose パターン
http://surferonwww.info/BlogEngine/post/2019/05/31/dispose-pattern.aspx

上の記事には以下の 2 つの例を書きました。

(1) Dispose パターンを実装した .NET のクラスのインスタンスを保持している。

(2) クラス内でアンマネージドリソースを取得し、それを保持している。

他に以下のケースもあると思いますが、

(3) Dispose パターンを実装済のクラスを継承したカスタムクラス。

それについては以下の記事に書きましたので、興味があれば読んでください。

Dispose パターン (その 2)
http://surferonwww.info/BlogEngine/post/2020/06/20/dispose-pattern-2nd.aspx

引用返信 編集キー/
■96717 / inTopicNo.5)  Re[2]: Disposeメソッドを付けないクラスの開放について
□投稿者/ ルーキー (2回)-(2021/01/14(Thu) 15:01:30)
774RR 様、WebSurfer様

ご返答ありがとうございます。
このような場合、基本的にGC任せで良いと理解できました。

またWebSurfer様のDispose パターンというものがあるのは初耳でまた1つ勉強になりました。
参考リンクを確認し、勉強いたします。

ありがとうございました。

解決済み
引用返信 編集キー/
■96718 / inTopicNo.6)  Re[3]: Disposeメソッドを付けないクラスの開放について
□投稿者/ 774RR (858回)-(2021/01/14(Thu) 16:51:54)
参照型の場合 a=null; を書いてもそこで gc を発生させることができるわけではないし
書かなくても「ソースコードのフロー解析上もう使っていない」と判断されたらいつでも処分されうるし
C++ の RAII に慣れている人が C# に移行するとハマるパターン

多重起動を禁止するのに Mutex で排他するつもりで Program.cs 中の Main() にて

static void Main()
{
    Mutex m = new Mutex(false, "MyOwnName");
    Application.Run(new Form1());
}

みたいに書くと m は Application.Run() の前に処分される可能性すらあるです。
文脈解析上 m は Application.Run() の時点でもう使われていないので。

ということでマネージされているリソースは gc に全部お任せしましょう。
GC.Collect() を自分で呼ぶのも原則禁止(呼ぶべき状況か判断できないときは呼ぶな)

解決済み
引用返信 編集キー/
■96719 / inTopicNo.7)  Re[4]: Disposeメソッドを付けないクラスの開放について
□投稿者/ ルーキー (3回)-(2021/01/14(Thu) 17:50:41)
774RR 様

追加のご返答ありがとうございます。

下手に処理しようとせず、任せるべきってことですね。
そのようにいたします。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ