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

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

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

Re[8]: disposeすべきobjectの判断は?


(過去ログ 62 を表示中)

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

■35580 / inTopicNo.1)  disposeすべきobjectの判断は?
  
□投稿者/ hirosi (7回)-(2009/05/10(Sun) 06:12:55)

分類:[.NET 全般] 

.net全般についての質問です。

表題の件ですが、全てのオブジェクトに対してdisposeする(呼ぶ)必要は無いと思いますが
しなければいけない(すべき?)オブジェクトはどのように判断すればよいでしょうか。

自分で作ったクラスであれば、disposeであれこれしてるから呼び出そう、、となりますが
そうでないものはイマイチ分かりません。

取り合えず、データベース系とかグラフィック系とかはしなきゃいけないんだろうなぁ・・・
なんて考えからdisposeを呼ぶようにしてますが、他に関しては呼んでいません。

それと、connectionとかはdisposeを呼べばcloseは呼ばなくて良いのでしょうか。
どこまでやってくれてるのかわかりずらいです。。。

取り合えず、close + dispose をする様にしていますが。

よろしくお願いいたします。
引用返信 編集キー/
■35583 / inTopicNo.2)  Re[1]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1130回)-(2009/05/10(Sun) 09:15:38)
渋木宏明(ひどり) さんの Web サイト
> 表題の件ですが、全てのオブジェクトに対してdisposeする(呼ぶ)必要は無いと思いますが
> しなければいけない(すべき?)オブジェクトはどのように判断すればよいでしょうか。

すべての場合をカバーする、汎用的な基準はありません。

個々のクラスの実装や、利用の仕方によっても、どうするべきかは変わります。

>取り合えず、データベース系とかグラフィック系とかはしなきゃいけないんだろうなぁ・・・

クラスの種別は関係ありません。

クラスが IDisposable インターフェースを実装しているなら、クラスインスタンスが回収されて消滅するまでに IDisposable.Dispose() が呼び出されなければなりません。

ですが、その IDisposable.Dispose() 呼び出しをいつだれが行うべきか?というのは、状況によって異なるのです。

> それと、connectionとかはdisposeを呼べばcloseは呼ばなくて良いのでしょうか。

「どの」コネクションでしょう?

SqlConnection は IDisposable.Dispose(), または Close() のどちらかを呼び出せばよいようですが、ODP.NET かなんかで、どちらか一方だけではダメなものがあったような。(決してそれが良い実装とは言えませんが)

引用返信 編集キー/
■35609 / inTopicNo.3)  Re[1]: disposeすべきobjectの判断は?
□投稿者/ ぱぱいやん (15回)-(2009/05/11(Mon) 09:30:11)
ぱぱいやん さんの Web サイト
No35580 (hirosi さん) に返信

> 自分で作ったクラスであれば、disposeであれこれしてるから呼び出そう、、となりますが
> そうでないものはイマイチ分かりません。

そうですね。
これって、結局クラスの「このプロパティの意味って何だろう?」とか「このメソッドって何をしているの?」というのと同じレベルの話なんですよね。

> 取り合えず、データベース系とかグラフィック系とかはしなきゃいけないんだろうなぁ・・・

上記の通りなので、一概には言えないです。

> なんて考えからdisposeを呼ぶようにしてますが、他に関しては呼んでいません。

僕は、基本的に常に呼ぶ方を基準にしています。
リソースを食いつぶすリスクより、結果的に Dispose が二重で呼ばれてしまった場合のリスクの方が低いというか、被害が少ない気がするので。
引用返信 編集キー/
■35639 / inTopicNo.4)  Re[1]: disposeすべきobjectの判断は?
□投稿者/ Jitta on the way (317回)-(2009/05/11(Mon) 20:28:31)
2009/05/11(Mon) 20:34:01 編集(投稿者)

No35580 (hirosi さん) に返信
> .net全般についての質問です。
>
> 表題の件ですが、全てのオブジェクトに対してdisposeする(呼ぶ)必要は無いと思いますが
> しなければいけない(すべき?)オブジェクトはどのように判断すればよいでしょうか。

マイクロソフトから提供されているクラスについては、MSDN ライブラリで確認します。
その他の会社から提供されているクラスは、その説明書を参照します。
自分でクラスを作る場合は、ドキュメントに必ず記載します。


ドキュメントが全てです。


追記
2.0に、Dispose でも Close でもないクラスがひとつ、あったと記憶しています。IDisposable を継承していますが、インテリセンスには dispose も close も出てこないので、解放のタイミングが意図しない状態になります。暗号系のクラスだったような気がします。
引用返信 編集キー/
■35641 / inTopicNo.5)  Re[2]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1137回)-(2009/05/11(Mon) 21:58:30)
渋木宏明(ひどり) さんの Web サイト
> 2.0に、Dispose でも Close でもないクラスがひとつ、あったと記憶しています。IDisposable を継承していますが、インテリセンスには dispose も close も出てこないので、解放のタイミングが意図しない状態になります。暗号系のクラスだったような気がします。

IDisposable を明示的に実装しているんですね。

そーゆーのは using するか、IDisposable にキャストして Dispose() を呼び出すことになります。

引用返信 編集キー/
■35646 / inTopicNo.6)  Re[3]: disposeすべきobjectの判断は?
□投稿者/ hirosi (8回)-(2009/05/11(Mon) 22:51:44)
渋木宏明(ひどりさん、ぱぱいやんさん、Jitta on the wayさん
コメントありがとうございます。

No35583 (渋木宏明(ひどり) さん) に返信
> クラスの種別は関係ありません。
> クラスが IDisposable インターフェースを実装しているなら、クラスインスタンスが回収されて消滅するまでに IDisposable.Dispose() が呼び出されなければなりません。
やはりそうですか・・・
IDisposableを実装しているクラスというと殆どの様な気がしますが(;^_^A アセアセ・・・
確実にDisposeを行おうと思うと
using(xxxx) {
using(xxxx) {
using(xxxx) {
using(xxxx) {
}
}
}
}
こんな感じになっちゃうんでしょうかねぇ・・・
(確実にdisposeするためにはusingを使う事が推奨されているみたいなので)

StringBuilderなんて良く使うんですが、Dispose呼んでる箇所は1つも無かったりします(;^_^A アセアセ・・・

>>それと、connectionとかはdisposeを呼べばcloseは呼ばなくて良いのでしょうか。
> 「どの」コネクションでしょう?
すいません。説明不足でした。
OleDbConnectionの事を指しておりましたm(__)m


No35609 (ぱぱいやん さん) に返信
>>なんて考えからdisposeを呼ぶようにしてますが、他に関しては呼んでいません。
> 僕は、基本的に常に呼ぶ方を基準にしています。
> リソースを食いつぶすリスクより、結果的に Dispose が二重で呼ばれてしまった場合のリスクの方が低いというか、被害が少ない気がするので。
はい。そうしないと駄目見たいですね・・・
なんかVB6より悪くなったような・・・


No35639 (Jitta on the way さん) に返信
> マイクロソフトから提供されているクラスについては、MSDN ライブラリで確認します。
> その他の会社から提供されているクラスは、その説明書を参照します。
> 自分でクラスを作る場合は、ドキュメントに必ず記載します。
>
> ドキュメントが全てです。
やはり、ドキュメントをしっかり読まないと駄目なんですね。。。
ちなみに、私の場合C#を使うのは個人的ツール(まぁ、仕事で使うものですが)なので
ドキュメントは一切ありません。(;^_^A アセアセ・・・

>2.0に、Dispose でも Close でもないクラスがひとつ、あったと記憶しています。IDisposable を継承していますが、インテリセンスには dispose も close も出てこないので、解放のタイミングが意図しない状態になります。暗号系のクラスだったような気がします。
きっと、他にもまだ沢山あるんでしょうねぇ・・・(-_-#)
ひとまず、暗号系は今のところ使う予定は無いので(;^_^A アセアセ・・・

--------------------------------------------------------------------------
自分はIDisposableを実装する場合、必ず以下の様にするようにしています。

class test :IDisposable{
~test(){
Dispose()
}
public void Dispose(){
リソースの開放など
}
}
やり方的に正しいでしょうかねぇ?
上記の様なサンプルを見たことが無かったので不明です。
呼ばれるか呼ばれないかわからないDisposeだけだと不安です。
そもそも、なんでDisposeを自動で呼んでくれないんでしょうか・・・・


引用返信 編集キー/
■35647 / inTopicNo.7)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ hirosi (9回)-(2009/05/11(Mon) 22:55:53)
あれ?そう言えば、必ずDispose呼ばないといけないのであれば
ガベージコレクションになっても、ほとんど恩恵を受けてないような気がしますね(ーー;)

引用返信 編集キー/
■35650 / inTopicNo.8)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ よねKEN (330回)-(2009/05/11(Mon) 23:17:11)
2009/05/12(Tue) 13:43:46 編集(投稿者)

>>クラスの種別は関係ありません。
>>クラスが IDisposable インターフェースを実装しているなら、クラスインスタンスが回収されて消滅するまでに IDisposable.Dispose() が呼び出されなければなりません。
> やはりそうですか・・・
> IDisposableを実装しているクラスというと殆どの様な気がしますが(;^_^A アセアセ・・・

「ほとんど」というほどはIDisposableを実装しているクラスは多くないと思いますよ。

> 確実にDisposeを行おうと思うと
> using(xxxx) {
> using(xxxx) {
> using(xxxx) {
> using(xxxx) {
> }
> }
> }
> }
> こんな感じになっちゃうんでしょうかねぇ・・・
> (確実にdisposeするためにはusingを使う事が推奨されているみたいなので)

IDisposableを実装するクラスを一遍にたくさん使うような場面があれば、
そういう記述になる場合もあるかもしれませんが、
そんなにインデントが深くなるような場面は私は見たことはないですね。

> StringBuilderなんて良く使うんですが、Dispose呼んでる箇所は1つも無かったりします(;^_^A アセアセ・・・

というコメントからすると少し誤解があるように思えます。
StringBuilderクラスはIDisposableを実装していませんので、Disposeを呼ぶこともありません。
(「Dispose呼んでる箇所は1つも無」で正常ということです)

>>マイクロソフトから提供されているクラスについては、MSDN ライブラリで確認します。
>>その他の会社から提供されているクラスは、その説明書を参照します。
>>自分でクラスを作る場合は、ドキュメントに必ず記載します。
>>
>>ドキュメントが全てです。
> やはり、ドキュメントをしっかり読まないと駄目なんですね。。。
> ちなみに、私の場合C#を使うのは個人的ツール(まぁ、仕事で使うものですが)なので
> ドキュメントは一切ありません。(;^_^A アセアセ・・・

開発環境を使われていないか、あるいは、MSDNをインストールされていないという意味でしょうか?
例えば、Visual Studio 2008 Express Editionを使われている場合、特に意識せずインストールされていれば、
ドキュメント(MSDNライブラリ、ヘルプなども同意)もインストールされているはずですので、
各クラスの項を参照すれば、IDisposableインタフェースを実装しているかどうかは確認できます。

また、たとえPCにドキュメントをインストールしていなくてもネット上でも参照できます。
例えば、StringBuilderクラスのヘルプは以下のURLです。

http://msdn.microsoft.com/ja-jp/library/system.text.stringbuilder(VS.80).aspx

>> C#
>> [SerializableAttribute]
>> [ComVisibleAttribute(true)]
>> public sealed class StringBuilder : ISerializable

これは上記URLからの引用ですが、StringBuilderクラスの定義部分が記載されており、
IDisposable を実装するクラスの場合、上記引用の中の「ISerializable」の部分に
「IDisposable」という文言も登場しますので、これで判断できます。

> --------------------------------------------------------------------------
> 自分はIDisposableを実装する場合、必ず以下の様にするようにしています。
>
> class test :IDisposable{
> ~test(){
> Dispose()
> }
> public void Dispose(){
> リソースの開放など
> }
> }
> やり方的に正しいでしょうかねぇ?

おおまかには合っていると思います。細かいことを言えば少し指摘事項はありますが、
その手の情報については「Dispose Finalize パターン」といったキーワードでWebを検索してみてください。

> 呼ばれるか呼ばれないかわからないDisposeだけだと不安です。
> そもそも、なんでDisposeを自動で呼んでくれないんでしょうか・・・・

>>~test(){
>> Dispose()
>>}

というコードを書かれていますが、これがその自動で呼んでくれる仕掛けですけど(^^;

デストラクタ(.NET Framework的にはFinalizeメソッド)が定義されていると
GCが動いてメモリ回収されるときにデストラクタが呼ばれます。
なので、その中でDisposeメソッドを呼び出すようにコーディングをしておくと
Disposeメソッドも最終的には呼び出されます。

この説明には、少し正確でない内容が含まれていますので、
いずれにせよ「Dispose Finalize パターン」といったキーワードでWebを検索してみてください。

<修正>
検索キーワードの(正)Disposeが(誤)Diposeになっていたので修正。
</修正>

引用返信 編集キー/
■35651 / inTopicNo.9)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ Azulean (367回)-(2009/05/11(Mon) 23:18:59)
> IDisposableを実装しているクラスというと殆どの様な気がしますが(;^_^A アセアセ・・・
> 確実にDisposeを行おうと思うと
> using(xxxx) {
> using(xxxx) {
> using(xxxx) {
> using(xxxx) {
> }
> }
> }
> }
同じスコープで良いのであれば、

using (xxxxx)
using (xxxxx)
using (xxxxx)
{ /* 上の3つの変数の有効範囲 */ }

というように書くことはできます。

> 自分はIDisposableを実装する場合、必ず以下の様にするようにしています。
こういうページもあります。
http://msdn.microsoft.com/ja-jp/library/fs2xkftw.aspx

なお、ファイナライザの時点ではメンバー変数にあるマネージクラスは先にファイナライズ済みかもしれません。
このため、ファイナライザから呼び出されるコードで、(参照型の)メンバー変数にアクセスするのはよくありません。

Disposeのよくある実装例としては、IDisposable.DisposeからDispose(true)を呼び、ファイナライザからはDispose(false)を呼ぶ。Dispose(bool)のメソッドはオーバーライドを認めておき、引数がtrueかfalseかで処理を分ける。


> そもそも、なんでDisposeを自動で呼んでくれないんでしょうか・・・・
前述の通り、そのまま呼んじゃまずいケースがあるので。

引用返信 編集キー/
■35652 / inTopicNo.10)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1140回)-(2009/05/11(Mon) 23:33:06)
渋木宏明(ひどり) さんの Web サイト
> 確実にDisposeを行おうと思うと
(略)
> こんな感じになっちゃうんでしょうかねぇ・・・

C# では

using(xxxx)
using(xxxx)
using(xxxx)
using(xxxx)
{
}

とも書けます。

> (確実にdisposeするためにはusingを使う事が推奨されているみたいなので)

IDisposable を明示的に実装していて、かつ Dispose() や Close() のような後片付け用のメソッドを実装していない場合なんかもありますしね。

> StringBuilderなんて良く使うんですが、Dispose呼んでる箇所は1つも無かったりします(;^_^A アセアセ・・・

StringBuilder は IDisposable インターフェースを実装してないと思いますけど?

> なんかVB6より悪くなったような・・・

C#, VB.NET は純粋な RAD 指向じゃないので。

> ちなみに、私の場合C#を使うのは個人的ツール(まぁ、仕事で使うものですが)なので
> ドキュメントは一切ありません。(;^_^A アセアセ・・・

MSDN ライブラリ(ヘルプ)は無償で閲覧することができますけど?

MSDN ライブラリ
http://msdn.microsoft.com/ja-jp/library/default.aspx

> 自分はIDisposableを実装する場合、必ず以下の様にするようにしています。
(略)
> やり方的に正しいでしょうかねぇ?

ヘルプで「Disposable パターン」が説明されているので、それを参考に実装してください。

> そもそも、なんでDisposeを自動で呼んでくれないんでしょうか・・・・

呼べないからです。

.NET の GC はユーザコードと非同期に実行されるので、ユーザコードがスコープを抜けた、などの IDisposable.Dispose() を呼び出すべきタイミングを知ることができません。

引用返信 編集キー/
■35653 / inTopicNo.11)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1141回)-(2009/05/11(Mon) 23:35:33)
渋木宏明(ひどり) さんの Web サイト
> あれ?そう言えば、必ずDispose呼ばないといけないのであれば
> ガベージコレクションになっても、ほとんど恩恵を受けてないような気がしますね(ーー;)

受けてないですよ。

GC が管理するのはあくまで、メモリ資源だけです。

GC 管理外の資源の破棄のタイミングを管理する目的で導入されたのが、IDisosable インターフェースです。

引用返信 編集キー/
■35657 / inTopicNo.12)  Re[3]: disposeすべきobjectの判断は?
□投稿者/ Jitta on the way (318回)-(2009/05/12(Tue) 07:42:32)
No35641 (渋木宏明(ひどり) さん) に返信
>>2.0に、Dispose でも Close でもないクラスがひとつ、あったと記憶しています。IDisposable を継承していますが、インテリセンスには dispose も close も出てこないので、解放のタイミングが意図しない状態になります。暗号系のクラスだったような気がします。
>
> IDisposable を明示的に実装しているんですね。
>
> そーゆーのは using するか、IDisposable にキャストして Dispose() を呼び出すことになります。
>

あ、ごめんなさい。上半分に絡めて、「ドキュメントを確認しないとわからないよ」の意図です。

引用返信 編集キー/
■35658 / inTopicNo.13)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ Jitta on the way (319回)-(2009/05/12(Tue) 07:53:31)
No35646 (hirosi さん) に返信
>>マイクロソフトから提供されているクラスについては、MSDN ライブラリで確認します。
>>その他の会社から提供されているクラスは、その説明書を参照します。
>>自分でクラスを作る場合は、ドキュメントに必ず記載します。
>>
>>ドキュメントが全てです。
> やはり、ドキュメントをしっかり読まないと駄目なんですね。。。
> ちなみに、私の場合C#を使うのは個人的ツール(まぁ、仕事で使うものですが)なので
> ドキュメントは一切ありません。(;^_^A アセアセ・・・

「一切ない」のは、「hirosiさんが作っているもの」ですよね?それについては、「作らなければなりません」。
利用するものについては、提供もとがドキュメントを用意しているはずです。



>
> >2.0に、Dispose でも Close でもないクラスがひとつ、あったと記憶しています。IDisposable を継承していますが、インテリセンスには dispose も close も出てこないので、解放のタイミングが意図しない状態になります。暗号系のクラスだったような気がします。
> きっと、他にもまだ沢山あるんでしょうねぇ・・・(-_-#)

「disposeかcloseすれば安全」みたいな意見に反証するために探し回ったので、マイクロソフト実装ではひとつだけだと思います。



> 自分はIDisposableを実装する場合、必ず以下の様にするようにしています。
>
> class test :IDisposable{
> ~test(){
> Dispose()
> }
> public void Dispose(){
> リソースの開放など
> }
> }
> やり方的に正しいでしょうかねぇ?
> 上記の様なサンプルを見たことが無かったので不明です。
> 呼ばれるか呼ばれないかわからないDisposeだけだと不安です。
> そもそも、なんでDisposeを自動で呼んでくれないんでしょうか・・・・
>
>
まず、MSDN ライブラリを読みましょう。IDispose の実装方法について解説してある章があります。
また、「マネージド リソース」と「アンマネージド リソース」の違いも、もう少し知る必要があると思います。
引用返信 編集キー/
■35661 / inTopicNo.14)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ ぱぱいやん (17回)-(2009/05/12(Tue) 09:17:57)
ぱぱいやん さんの Web サイト
> ■No35609 (ぱぱいやん さん) に返信
> >>なんて考えからdisposeを呼ぶようにしてますが、他に関しては呼んでいません。
>>僕は、基本的に常に呼ぶ方を基準にしています。
>>リソースを食いつぶすリスクより、結果的に Dispose が二重で呼ばれてしまった場合のリスクの方が低いというか、被害が少ない気がするので。
> はい。そうしないと駄目見たいですね・・・
> なんかVB6より悪くなったような・・・

マネージドリソースが使えるメリットとの相殺じゃないかと思います。
単に using や Dispose メソッドを呼び出ば良いだけと考えることもできます。
引用返信 編集キー/
■35662 / inTopicNo.15)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ ぱぱいやん (18回)-(2009/05/12(Tue) 09:21:11)
ぱぱいやん さんの Web サイト
No35647 (hirosi さん) に返信
> あれ?そう言えば、必ずDispose呼ばないといけないのであれば
> ガベージコレクションになっても、ほとんど恩恵を受けてないような気がしますね(ーー;)

GC と、Dispose は同じ線上で語るようなものではないと思いますよ。
実際、ピープメモリをを気軽に使いまくって後片づけしなくてよいのは、GC のおかげです。
ですから、オブジェクトを生成する場面の多くは GC の恩恵を受けていることになります。
引用返信 編集キー/
■35665 / inTopicNo.16)  Re[4]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1142回)-(2009/05/12(Tue) 10:19:26)
渋木宏明(ひどり) さんの Web サイト
> あ、ごめんなさい。上半分に絡めて、「ドキュメントを確認しないとわからないよ」の意図です。

はい。ドキュメントは読まなければならない(=個々のクラスの仕様の確認はしなければならない)ですね。

>>そーゆーのは using するか、IDisposable にキャストして Dispose() を呼び出すことになります。

は「そーなる可能性が高い」ことが推定されますが、そうでないこともあるし、何もする必要がない場合すらあり得ます。


引用返信 編集キー/
■35675 / inTopicNo.17)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ よりみち (1回)-(2009/05/12(Tue) 13:12:06)
この質問に便乗させてください。

上記をまとめると、IDisposableインターフェースを実装しているクラスは、
使用後は、全てDisposeしないといけないのでしょうか?

マネージドリソースの場合、
GCが回収してくれるので、安易にDisposeすると、
レスポンスが悪くなると聞いたことがあります。

再利用する場合は、Disposeする必要があるかと思いますが、
例えば、DataSetやDataTableなんかも、使用後はDisposeする必要があるんでしょうか?

またWindowsFormのOnPaintイベントでは、
e.GraphicsをDisposeするといかんといった記述をどこかで見た気が…。
引用返信 編集キー/
■35677 / inTopicNo.18)  Re[6]: disposeすべきobjectの判断は?
□投稿者/ Hongliang (379回)-(2009/05/12(Tue) 13:30:19)
> 上記をまとめると、IDisposableインターフェースを実装しているクラスは、
> 使用後は、全てDisposeしないといけないのでしょうか?
大抵はした方がいい、ぐらいです。「しなければまずい」もあれば「する必要はない」もあります。そのクラス自身の設計にも、利用者側の設計にも依ります。
スコープ一つですむなら必ず using する、ぐらいならやっといた方がいいでしょう。
ただ、IDisposable なオブジェクトの参照があっちこっちにちらばってしまう場合、誰がいつ Dispose を呼び出すのか決定できないことも考えられますからね。

> マネージドリソースの場合、
> GCが回収してくれるので、安易にDisposeすると、
> レスポンスが悪くなると聞いたことがあります。
それは Dispose じゃなくて GC.Collect の話だと思います。
GC が動いたときに生き残ったオブジェクトは寿命が延びるので、不必要な GC.Collect の呼び出しはマネージドメモリの圧迫を招き、次の GC の発動が早くなったりするでしょう。

> 再利用する場合は、Disposeする必要があるかと思いますが、
> 例えば、DataSetやDataTableなんかも、使用後はDisposeする必要があるんでしょうか?
基本的になかったはずですね。基底クラスの MarshalByRefOBject が実装しているから Dispose を持っているに過ぎないはず。

> またWindowsFormのOnPaintイベントでは、
> e.GraphicsをDisposeするといかんといった記述をどこかで見た気が…。
自分で作ったものではないものですから。
// 「自分で作る」の基準も結構曖昧ですけどね。new キーワードなら明らかですが、Graphics.FromImage みたいなメソッドの返値だと……。
引用返信 編集キー/
■35679 / inTopicNo.19)  Re[6]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1143回)-(2009/05/12(Tue) 13:39:23)
渋木宏明(ひどり) さんの Web サイト
> 使用後は、全てDisposeしないといけないのでしょうか?

原則として、いつか、どこかで、だれかが(あなたとは限りません)IDisposable.Dispose() を呼び出さなければなりません。

例外は、IDisposable インターフェースを継承していても、実際にはクラスインスタンスがアンマネージリソースをカプセルしていない場合です。

> マネージドリソースの場合、
> GCが回収してくれるので、安易にDisposeすると、
> レスポンスが悪くなると聞いたことがあります。

僕はありません。
出典は何ですか?

レスポンスが劣化することになろうとも、必要な処理は行わないわけにはいきません。
それがまずいなら、段取りを変えるしかありません。

> 例えば、DataSetやDataTableなんかも、使用後はDisposeする必要があるんでしょうか?

それらは Component 派生クラスであるが故に IDisposable インターフェースを継承しています。

ですが、実際にはまったくアンマネージリソースをカプセルしていない実装もありえます。
そこんところに自信があるなら、プログラマの責任において IDisposable.Dispose() 呼び出しを省略するのはアリでしょう。

> またWindowsFormのOnPaintイベントでは、
> e.GraphicsをDisposeするといかんといった記述をどこかで見た気が…。

ダメですよ。

「いつか、どこかで、だれかが行うべき」なだけであって、「常にあなたが行うべき」なのではありません。

OnPaint() の引数で渡される e.Graphics は Windows.Forms が管理している Graphics のインスタンス(=あなたから見れば借り物)なので、あなたが IDiposable.Dispose() 呼び出しを行うべきではありません。

「IDisposable.Dispose() を自分で呼び出すべきかどうか」を判断するためには、型や Dispsoe(), Close() メソッドのあるなしだけに注目するのではなく、「状況」も考慮しなければならないのです。

引用返信 編集キー/
■35680 / inTopicNo.20)  Re[6]: disposeすべきobjectの判断は?
 
□投稿者/ よねKEN (331回)-(2009/05/12(Tue) 13:40:05)
2009/05/12(Tue) 13:44:41 編集(投稿者)

#投稿文書いている間にHongliangさんの投稿が・・・

No35675 (よりみち さん) に返信
> 上記をまとめると、IDisposableインターフェースを実装しているクラスは、
> 使用後は、全てDisposeしないといけないのでしょうか?

基本的に(※1)、誰がDisposeを呼ぶのか?(※2)という点は別にして
最終的にはDisposeメソッドが呼ばれなければなりません。

※1 基本的に
 IDisposable.Disposeを実装しているクラスでも、
 Disposeの実装が単なる空実装であれば、Disposeメソッドを呼ばなくても、
 害がありませんので、"基本的に"と書きました。とはいえ、
 実装者以外にはその区別ができるとは限らないので、
 常に呼ぶべきという考えで問題ないと思います。

※2 誰がDisposeするのか?
 自分で作成したインスタンスで自分しか使わないものであれば、
 自分がDisposeすることができますし、Disposeするべきです。
 しかし、他人が作成したインスタンスを自分が利用させてもらっている場合、
 自分が作成したインスタンスを他人に利用させている場合、
 つまり、自分以外の誰かがそのインスタンスを利用している可能性がある場合、
 そのインスタンスは誰かが使用中である可能性があるため、
 Disposeメソッドを呼び出してはいけない場合があります。

> マネージドリソースの場合、
> GCが回収してくれるので、安易にDisposeすると、
> レスポンスが悪くなると聞いたことがあります。

「安易にDisposeすると」のところは、「安易にFinalizeメソッドをオーバーライドする(C#ではデストラクタを定義する)と」の間違いではないでしょうか。

IDisposable.Disposeを実装しているクラスで、自分でDisposeメソッドを呼んでおいた場合、GC回収時のそのクラスのFinalizeメソッドの呼び出し処理が軽くなると予想されるので、微々たるものだと思いますが、逆にGC処理のパフォーマンスは上がると思います。(「Dispose Finalize パターン」が正しく実装されている前提です)


引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -