回答:
他のいくつかが一般的に指摘しているように、これは問題ではありません。
これが問題を引き起こす唯一のケースは、usingステートメントの途中で戻り、さらにin using変数を返す場合です。しかし、繰り返しますが、これは、変数への参照を返さずにそのまま保持したとしても、問題を引き起こします。
using ( var x = new Something() ) {
// not a good idea
return x;
}
同様に悪い
Something y;
using ( var x = new Something() ) {
y = x;
}
return
文がusing
ブロックの終わりをコードパスからアクセスできないようにするためだと思います。using
必要に応じてオブジェクトを破棄できるように、ブロックの最後を実行する必要があります。
まったく問題ありません。
あなたはどうやら
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
盲目的に翻訳されます:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
確かに、これは問題となり、using
ステートメントをかなり無意味なものにします---それが理由でそうではありません。
コンパイラは、オブジェクトがブロックを離れる方法に関係なく、制御がブロックを離れる前にオブジェクトが確実に破棄されるようにします。
以下のコードは、どのように機能しているかを示していますusing
。
private class TestClass : IDisposable
{
private readonly string id;
public TestClass(string id)
{
Console.WriteLine("'{0}' is created.", id);
this.id = id;
}
public void Dispose()
{
Console.WriteLine("'{0}' is disposed.", id);
}
public override string ToString()
{
return id;
}
}
private static TestClass TestUsingClose()
{
using (var t1 = new TestClass("t1"))
{
using (var t2 = new TestClass("t2"))
{
using (var t3 = new TestClass("t3"))
{
return new TestClass(String.Format("Created from {0}, {1}, {2}", t1, t2, t3));
}
}
}
}
[TestMethod]
public void Test()
{
Assert.AreEqual("Created from t1, t2, t3", TestUsingClose().ToString());
}
出力:
「t1」が作成されます。
「t2」が作成されます。
「t3」が作成されます。
「t1、t2、t3から作成」が作成されます。
't3'は破棄されます。
't2'は破棄されます。
't1'は破棄されます。
破棄は、returnステートメントの後、関数の終了前に呼び出されます。
たぶん、これが許容できるということは100%真実ではありません...
を使用してネストし、ネストされたものから戻る場合は、安全ではない可能性があります。
これを例にとります:
using (var memoryStream = new MemoryStream())
{
using (var textwriter = new StreamWriter(memoryStream))
{
using (var csv = new CsvWriter(textwriter))
{
//..write some stuff to the stream using the CsvWriter
return memoryStream.ToArray();
}
}
}
DataTableを渡してcsvとして出力していました。途中で戻ると、すべての行がストリームに書き込まれていましたが、出力されたcsvには常に行(またはバッファーのサイズによっては複数)がありませんでした。これにより、何かが適切に閉じられていなかったことがわかりました。
正しい方法は、以前のすべての使用が適切に破棄されていることを確認することです。
using (var memoryStream = new MemoryStream())
{
using (var textwriter = new StreamWriter(memoryStream))
{
using (var csv = new CsvWriter(textwriter))
{
//..write some stuff to the stream using the CsvWriter
}
}
return memoryStream.ToArray();
}