7

私は今日いくつかのコードを書きました、そしてそれはそれがより安全であると言った別の開発者によって変更されました。ここで行われたことの利点がわからないため、これが正しいかどうかはわかりません。いくつかのコード例があります

public byte[] ReadFile(Stream stream)
{
    byte[] result = null;

    try
    {
       // do something with stream
       result = <result of operation>
    }
    finally
    {
        stream.Close();
    }

    return result;
}

これはに変更されました

public byte[] ReadFile(Stream stream)
{
    byte[] result = null;

    // do something with stream
    result = <result of operation>

    return result;
}

私はc#を使い終わったときにストリームを閉じてはいけないので、まったく新しいです。

4

7 に答える 7

11

一般的に、最初のバージョンは悪いデザインになります。

はい、ストリームを閉じる必要がありますが、できれば、ストリームを開いたのと同じコード(同じメソッド)で閉じる必要があります。これは関心の分離と呼ばれ、間違いや混乱の可能性がはるかに低くなります。

だからどちらか

  • ReadFile()たとえば、aを受け入れ、string fileNameストリームを開いたり閉じたりします。
  • 発信者に任せます。

メソッド(2番目のバージョン)は次のように使用する必要があります。

using (var reader = new FileReader(...))
{
  // maybe some pre-reading
  var r = ReadFile(reader);
  // maybe some post-reading
}

2番目のアプローチでも、メソッドの再利用性が向上することに注意してください。

于 2012-04-05T20:19:55.673 に答える
6

この質問に対する正しい答えはありません。アプリのアーキテクチャによって異なるためです。

はい、この関数で作成されておらず、使用されstreamているだけの場合、そうです。それを閉じると、呼び出し元に任せましょう。

ただし、繰り返しますが、アプリのアーキテクチャによって異なります。

于 2012-04-05T20:20:14.557 に答える
5

ドアを開ける人は、ドアを閉めることを忘れないでください。

したがって、ストリームを開いたメソッドでストリームを閉じる方が適切です。

于 2012-04-05T20:20:32.080 に答える
3

通常、ストリームの作成者は、ストリームを閉じる人である必要があります。理想的には、usingブロックを使用してストリームを破棄します。

using (var myStream = getMeAStream()) {
    ReadFile(myStream);

    // If you want to be really sure it is closed:
    myStream.Close();
    // Probably not neccessary though, since all 
    // implementations of Stream should Close upon Disposal
}
于 2012-04-05T20:21:33.693 に答える
1

ストリームは他の何かによってこの関数に渡されました。関数を閉じる責任はありません。その問題に対処するのは呼び出し元のコード次第です。

その理由は、この関数の外部で別の操作(リセットや別の読み取りなど)を実行する必要がある場合があり、関数を閉じると例外が発生するためです。

私は、最終的に誰かが私に耳を傾けるまで、このようなコードを1日に数回リファクタリングしていました。

この種のコードによって引き起こされる深刻なバグを少なくとも1つ見たので、一般的には悪い考えです

于 2012-04-05T20:22:38.647 に答える
0

コードレビューは正しかった-そのようなことは絶対にしないでください(または、そのようなことを外部のコードで必要とする場合、そのコードはおそらく適切に設計されていません-例外はありますが、ストリームのようなものについてはほとんどありません、そしていくつかのデフォルト'パターンは常に従う必要があります)。
ほとんどの場合、このようなストリームを使用します(「外部」から)...

using(Stream stream = new ...)
{
    ...call your method
}

(または、たとえば、読者がそれを破棄しています-しかし、どちらの場合もこのようなことを行うことをお勧めします-同等のものは' finally'ブロックを使用していますが、要約すると同じものになります)

...基本的に、呼び出し元の関数は、クラッシュするまで、「内部」で破棄したかどうかを知ることはありません。「両方の部分」がそのようなことに同意する場合、それはまだ受け入れられませんが、罰せられない可能性があります。

于 2012-04-05T20:21:27.413 に答える
0

これは単なるC#の問題ではありません。関数「ReadFile」の呼び出し後、他の操作にストリームを使用する必要がありますか?いいえの場合は、ファイルを読み取った後でストリームを閉じることを選択できます。ストリームを使い終わったら閉じる方が良いですが、他の操作にストリームが必要かどうかがわかる場所があるため、通常は開くよりも同じコンテキストでストリームを閉じる方が好きです。

Stream s = open_the_stream()
try {
  ReadFile(s)...
} finally {
  s.Close();
}

いずれにせよ、それらを使用するために終了するときはストリームを閉じてください。

于 2012-04-05T20:25:47.370 に答える