次の件についてご意見をお聞かせください。
1つの特定の目的を達成するためのメソッドがあると想像してください。しかし、そのためには、ローカルスコープのオブジェクトの重要な数のサポートが必要であり、それらの多くはを実装していますIDisposable
。
MSコーディング標準IDisposable
では、メソッドのスコープを「存続」する必要のないローカルオブジェクトを使用する場合(たとえば、返されることも、より長く存続する状態情報に割り当てられることもありませんobject
)、構成を使用する必要がありますusing
。
using
問題は、状況によっては、ネストされたブロックの「地獄」を取得できることです。
using (var disposableA = new DisposableObjectA())
{
using (var disposableB = new DisposableObjectB())
{
using (var disposableC = new DisposableObjectC())
{
//And so on, you get the idea.
}
}
}
使用しているオブジェクトの一部が共通ベースから派生している場合、またはを実装する共通interface
を実装している場合は、どういうわけかこれを軽減できますIDisposable
。もちろん、これには、オブジェクトの真のタイプが必要なときはいつでも、前述のオブジェクトをキャストする必要があるという犠牲が伴います。キャストの量が手に負えない限り、これは実行可能である場合があります。
using (var disposableA = new DisposableObjectA())
{
using (DisposableBaseObject disposableB = new DisposableObjectB(),
disposableC = new DisposableObjectC)
{
using (var disposableD = new DisposableObjectD())
{
//And so on, you get the idea.
}
}
}
もう1つのオプションは、ブロックを使用せず、using
ブロックを直接実装することtry-catch
です。これは次のようになります。
DisposableObjectA disposableA = null;
DisposableObjectB disposableB = null;
DisposableObjectC disposableC = null;
...
try
{
disposableA = new DisposableObjectA();
....
}
finally
{
if (disposableA != null)
{
disposableA.Dispose();
}
if (disposableB != null)
{
disposableB.Dispose();
}
//and so on
}
面白いことに、VSCodeAnalyzerはこのコードに「間違った」というフラグを立てます。すべての可能な実行パスが、スコープ外になる前にすべての使い捨てオブジェクトが破棄されることを保証するわけではないことを通知します。私の意見では決して起こらないはずのオブジェクトが破棄中にスローされた場合にのみ発生することがわかります。発生した場合、通常は何かが本当に混乱しているという兆候があり、おそらくあなたと同じくらい速く優雅に終了する方が良いでしょうアプリ全体からできます。
ですから、問題は、どのアプローチがより好きかということです。ブロックの数に関係なく、ネストされたブロックを使用することが常に望ましいですusing
か、または特定の制限を超えると、try-catch
ブロックを使用する方が良いですか?