65

次のような状況がある場合:

StreamWriter MySW = null;
try
{
   Stream MyStream = new FileStream("asdf.txt");
   MySW = new StreamWriter(MyStream);
   MySW.Write("blah");
}
finally
{
   if (MySW != null)
   {
      MySW.Flush();
      MySW.Close();
      MySW.Dispose();
   }
}

Close が提供されていても、Closeを呼び出しMySW.Dispose()てスキップすることはできますか? 期待どおりに動作しないストリームの実装はありますか (CryptoStream など)?

そうでない場合、次のコードは単に悪いコードです。

using (StreamWriter MySW = new StreamWriter(MyStream))
{
   MySW.Write("Blah");
}
4

8 に答える 8

3

Stream クラスの .net ソースを調べたところ、次のような記述がありました。

    // Stream used to require that all cleanup logic went into Close(),
    // which was thought up before we invented IDisposable.  However, we 
    // need to follow the IDisposable pattern so that users can write
    // sensible subclasses without needing to inspect all their base
    // classes, and without worrying about version brittleness, from a
    // base class switching to the Dispose pattern.  We're moving 
    // Stream to the Dispose(bool) pattern - that's where all subclasses
    // should put their cleanup starting in V2. 
    public virtual void Close() 
    {
        Dispose(true); 
        GC.SuppressFinalize(this);
    }

    public void Dispose() 
    {
        Close(); 
    } 
于 2012-02-15T22:04:16.893 に答える
3

StreamWriter.Dispose() と Stream.Dispose() はどちらも、オブジェクトが保持しているすべてのリソースを解放します。どちらも基になるストリームを閉じます。

Stream.Dispose() のソース コード (これは実装の詳細であるため、依存しないでください):

public void Dispose()
{
    this.Close();
}

StreamWriter.Dispose() (Stream.Dispose() と同じ):

protected override void Dispose(bool disposing)
{
    try
    {
        // Not relevant things
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {
            try
            {
                if (disposing)
                {
                    this.stream.Close();
                }
            }
            finally
            {
                // Not relevant things
            }
        }
    }
}

それでも、私は通常、それらを破棄する前にストリーム/ストリームライターを暗黙的に閉じます-見た目がきれいだと思います。

于 2009-05-26T16:00:29.877 に答える
3

手動で閉じる必要があるオブジェクトの場合、using ブロックでオブジェクトを作成するためにあらゆる努力を払う必要があります。

//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
   //Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream' 

このようにして、using 句のコンテキストから「ストリーム」に誤ってアクセスすることは決してなく、ファイルは常に閉じられます。

于 2009-06-19T00:54:02.753 に答える
2

Stream.Closeへの呼び出しStream.Disposeまたはその逆によって実装されるため、メソッドは同等です。Stream.Closeストリームを破棄するよりもストリームを閉じる方が自然に聞こえるという理由だけで存在します。

さらに、このメソッドへの明示的な呼び出しを避け、using代わりにステートメントを使用して、正しい例外処理を無料で取得するようにしてください。

于 2009-05-26T15:58:06.840 に答える