最近、次のように記述されたコードを見ました。
public void Dipose()
{
using(_myDisposableField) { }
}
これは私にはかなり奇妙に思えます。myDisposableField.Dispose();
明示的に呼び出しを行うよりも、「使用」を使用してオブジェクトを破棄する理由は何ですか?
最近、次のように記述されたコードを見ました。
public void Dipose()
{
using(_myDisposableField) { }
}
これは私にはかなり奇妙に思えます。myDisposableField.Dispose();
明示的に呼び出しを行うよりも、「使用」を使用してオブジェクトを破棄する理由は何ですか?
いいえ、まったくありません。空にコンパイルされて、try/finally
を呼び出すことになりDispose
ます。
それを除く。コードをより速く、より読みやすく、そしておそらく最も重要なことに(以下を読み続けるにつれて)その意図をより表現力豊かにするでしょう。
更新:それらは少し賢く、同等のコードにはnullチェックが必要であり、Jon Skeetのアドバイスに従って、マルチスレッドが含まれる場合はローカルコピーも取得します(null間の競合を回避するための標準のイベント呼び出しパターンと同じ方法で)チェックとメソッド呼び出し)。
IDisposable tmp = _myDisposableField;
if (tmp != null)
tmp.Dispose();
私が書いたサンプルアプリのILで見ることができることから、あなたも直接_myDisposableField
として扱う必要があるようです。IDisposable
これは、いずれかのタイプがIDisposable
インターフェイスを明示的に実装し、同時にメソッドを提供する場合に重要になります。public void Dispose()
try-finally
このコードも、を使用するときに存在するものを複製しようとはしませんusing
が、これは不要であると見なされると想定されています。ただし、Michael Graczykがコメントで指摘しているように、オファーの使用は、例外、特に(いつでも発生する可能性がある)finally
例外に対する保護を提供します。ThreadAbortException
とはいえ、これが実際に発生するウィンドウは非常に小さいです。
しかし、私は彼らがこれを行ったという事実に5人を賭けて、それが彼らに与える微妙な「利益」を本当に理解していませんでした。
あなたが投稿した例には、非常に微妙ですが邪悪なバグがあります。
次のように「コンパイル」されます。
try {}
finally
{
if (_myDisposableField != null)
((IDisposable)_myDisposableField).Dispose();
}
オブジェクトは、外側ではなく、using 句内でインスタンス化する必要があります。
リソース オブジェクトをインスタンス化してから、変数を using ステートメントに渡すことができますが、これはベスト プラクティスではありません。この場合、制御が using ブロックを離れた後、オブジェクトはスコープ内にとどまりますが、おそらくそのアンマネージ リソースにはアクセスできません。つまり、完全に初期化されていません。using ブロックの外側でオブジェクトを使用しようとすると、例外がスローされる危険があります。このため、using ステートメントでオブジェクトをインスタンス化し、そのスコープを using ブロックに限定することをお勧めします。
—<a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement" rel="nofollow noreferrer">using ステートメント (C# リファレンス)
言い換えれば、それはダーティでハッキーです。
クリーン バージョンは、MSDN で非常に明確に綴られています。
using
、境界にコンストラクター呼び出しがあるブロックを使用します。Dispose
直接使用しないでください。最後に、管理されていないリソースIDisposable
を使用する場合にのみパターンを使用する必要があることに注意してください。それが本当に必要であることを確認してください:-)
using ステートメントは、参照されたオブジェクトを破棄する必要があるコードのスパンを定義します。
はい、一度 .dispose を呼び出すことはできますが、オブジェクトのスコープが何であるかはあまり明確ではありません (IMHO)。YMMV。