Stream
、などのクラスはStreamReader
インターフェースStreamWriter
を実装しますIDisposable
。つまり、Dispose()
これらのクラスのオブジェクトで メソッドを呼び出すことができます。また、public
というメソッドも定義されていますClose()
。オブジェクトを使い終わったら何を呼び出せばいいのかわからなくなってきました。両方を呼び出すとどうなるのでしょうか。
現在のコードは次のとおりです:
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
writer.Close();
}
reader.Close();
}
}
ご覧のとおり、各オブジェクトでメソッドusing()
を自動的に呼び出す構造を記述しましたDispose()
。しかし、メソッドも呼び出していますClose()
。これで正しいでしょうか?
ストリーム オブジェクトを使用する際のベスト プラクティスを教えてください。 :-)
MSDN の例では、コンストラクトを使用せずusing()
、Close()
メソッドを呼び出します。
いいですか?
ベストアンサー1
Reflector.NET に簡単にアクセスしてみると、次のClose()
メソッドがわかりますStreamWriter
。
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
そしてStreamReader
:
public override void Close()
{
this.Dispose(true);
}
オーバーライドDispose(bool disposing)
は次StreamReader
のとおりです。
protected override void Dispose(bool disposing)
{
try
{
if ((this.Closable && disposing) && (this.stream != null))
{
this.stream.Close();
}
}
finally
{
if (this.Closable && (this.stream != null))
{
this.stream = null;
/* deleted for brevity */
base.Dispose(disposing);
}
}
}
方法StreamWriter
は同様です。
Close()
したがって、コードを読むと、ストリームに対して& を好きなだけ、任意の順序で呼び出すことができることがわかりますDispose()
。動作はまったく変わりません。
Dispose()
したがって、およびClose()
/または を使用する方が読みやすいかどうかということになりますusing ( ... ) { ... }
。
私の個人的な好みとしては、using ( ... ) { ... }
ハサミで逃げないようにするために、可能な場合は常にこれを使用するべきだということです。
しかし、これは正確さには役立ちますが、可読性は低下します。C# にはすでに多数の閉じ中括弧があるので、どれが実際にストリームを閉じるのかをどうやって知るのでしょうか。
したがって、次のようにするのが最善だと思います:
using (var stream = ...)
{
/* code */
stream.Close();
}
コードの動作には影響しませんが、読みやすさは向上します。