私はガベージコレクションの理解を深め、管理されていないリソース&を管理しようとしています。また、「低レベル」のプログラミングやそのようなものに興味を持っているので、メモリ管理に関する「適切な設計原則」私はあなたがusing
ブロックまたはこれらのアンマネージリソースを確保するためのいくつかの他のソリューションを使用するをを想定していることを理解しDisposeを呼び出すのは正確に何ですか?
は、実際に配置されたのですか、私はボンネットの下に何が起こっているのか理解していません。
私はこの記事を見ていた:MSDNのImplementing a Dispose Methodと、この特定の行で混乱していた:リソースが常に適切にクリーンアップされることを確保するために
、Disposeメソッドは、スローせずに呼び出し可能な複数回でなければなりません例外。
彼らは処分パターンを提供するサンプルコードを見てみましょう:私は上記の引用されたテキストは、基本的に私たちができるように、私たちはbool disposed
プロパティを追加しました」、と言っているものを信じる
class DerivedClass : BaseClass
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Instantiate a SafeHandle instance.
SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
handle.Dispose();
// Free any other managed objects here.
}
// Free any unmanaged objects here.
disposed = true;
// Call base class implementation.
base.Dispose(disposing);
}
}
それはtrue
もしそうならreturn
だかどうかを確認します。それは、その後false
をなら、我々は実際のリソースを処分。我々は
しかし、これは私には意味がありませんでした。オブジェクトを取り除いてしまったら、もう一度Dispose
と呼ぶことができますか?記事から引用されたテキストを考えると、理にかなって -
var cmd = new SqlCommand();
cmd.Dispose();
cmd.Dispose();
これは、コンパイルし、問題なく実行されます。調査するために
は、私は以下の3行を含むコンソールアプリケーションを書きました。しかし、私はが実際にはが起こっていることを理解していません。
私はブレークポイントを設定し、各行を踏んだ。最初のDispose
が呼び出された後、私はcmd
がnull
であることをVisual Studioのローカルウィンドウが私に伝えることを期待しました。この思考の列に沿って、私は自分自身に尋ねました。「Dispose
をnull
に電話するにはどうすればいいですか?明らかに、あなたはできません。では何が起こっているのですか? cmd
はなぜ初めて処分された後にSqlCommand
オブジェクトですか?
Dispose
がやっている、と私は私の物を処分してしまった場合どう正確なぜまだ、すべての意図や目的のために存在するように見えるのでしょうか?
なぜ/次のようにコンパイルして問題なく実行できますか?
var cmd = new SqlCommand();
cmd.Dispose();
cmd.CommandText = "I figured this would throw an exception but it doesn't";
"under the hood"はありません。魔法は関係なく、それは他のどのような方法でもあります。 'Dispose'メソッドを書く人は、それを適切に実装する必要があります - 適切な' CloseHandle'関数などをすべて呼び出します。他の方法で "this reference"を "null"に変更できますか?もちろん違います。なぜあなたは 'Dispose'がそれをすることができると思いますか?単なる方法です。 – Luaan
Luaanの説明に加えて、より大きな画像はhttp://stackoverflow.com/questions/538060/proper-use-of-theididposable-interfaceも参照してください。 –
あなたは最悪の可能性のある例について、何も役に立ちませんでした(https://referencesource.microsoft.com/#System.Data/System/Data/SqlClient/SqlCommand.cs,1101)。おそらく、.NET 1.0では非常に異なったことをしました。しかし、あなたがそれを廃棄した後でも、オブジェクトを使用し続けることは確かにありません。うまくいけばそれはやや明白です。 ObjectDisposedExceptionをスローすることがあります。メンバーが「重い」ものを何もしないので、そうでないかもしれません。意図的に間違っていることはそれほど有用ではありません。 –