2012-03-30 9 views
11

IDisposableオブジェクトをusing(){}ステートメントにラップする必要がありますか?たとえば、次のような方法で:配置されているIDisposableオブジェクトでの使用をネストする必要がありますか?

public static string ReadResponse(HttpWebResponse response) 
{ 
    string resp = null; 
    using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
    { 
     resp = reader.ReadToEnd(); 
    } 
    return resp; 
} 

が、私は両方StreamStreamReaderに数えることができる:

public static string ReadResponse(HttpWebResponse response) 
{ 
    string resp = null; 
    using (Stream responseStream = response.GetResponseStream()) 
    { 
     using (StreamReader responseReader = new StreamReader(responseStream)) 
     { 
      resp = responseReader.ReadToEnd(); 
     } 
    } 
    return resp; 
} 

は、私はちょうど1 usingこのようにこれを統合してもらえますか?または、2つのusing文を使用する必要がありますか?

答えて

12

はい、あなたはをすることができますが、StreamReaderをコンストラクタのドキュメントは、特に言うのでそれはだ:「StreamReader.Disposeが呼び出されたときに、StreamReaderオブジェクトが提供Streamオブジェクト上の処分を呼び出します」

もしそうでなければ、少なくともこのコードを少しきれいにするためにこれを行うことができます。

using (Stream responseStream = response.GetResponseStream()) 
using (StreamReader responseReader = new StreamReader(responseStream)) 
{ 
    resp = responseReader.ReadToEnd(); 
} 
+0

大文字のインデントよりもはるかにクリーンなスタッキングを使用しています:-) –

+0

中括弧はオプションであると考えてください。 'if'ステートメントのような他のステートメントと同じ方法です。 "if(expression)if(expression2)if(expression3){/ *複数のコード行を記述するのに有効なコードです。* /} "各ifステートメントは前のステートメントの中に入れ子になっています –

+0

@Moozheコンパイルするのはそれほど驚くことではありませんが、VSがインデントをどのように扱うのですか? – Servy

2

私はこれはかなり興味深いアプリケーションの設計上の問題で、using文のネストの簡単な質問よりも、この問題が広くました。

(){}ステートメント、 を使用してすべてのIDisposableオブジェクトをラップする必要がありますか?

はい、あなたはIDisposableを実装するオブジェクトをインスタンス化しているので、 - あなたはそれを配置するのを認識している、using()または明示的なDispose()呼び出しでラップすることによってのいずれか。この背後にある

理由は、次のシナリオを想像単純です:あなたは次のエンティティ

  • TransportServiceの
  • ReportServiceの
  • FeedService

すべての道具IDisposableを持っています。 ReportServiceFeedServiceの両方とも、構築段階で渡されるインスタンスはTransportServiceである必要があります。そして、質問 - TransportServiceをReportServiceまたはFeedServiceのDispose()に配置するのは正しいですか?いいえ!両方のサービスで同じ移送サービスのインスタンスが渡され、移送が処理されると、これはすべてのサービスにも影響します。

public sealed class ReportService : IDisposable 
{  
    private readonly ITransportService transportService; 

    public ReportService(ITransportService transportService) 
    { 
     this.transportService = transportService; 
    } 

    public Dispose() 
    { 
     // ReportService should not dispose objects 
     // passed in since they could be used by other classes as well 
     // DO NOT: transportService.Dispose(); 
    } 
} 
+1

これは実際には「常に処分する」または「決して処分しない」という質問ではありません。使い捨てオブジェクトを渡すときは2つのパスがありますあなたがそれを処分する責任を失ったことをあなたがもう忘れているならば、それが処分されたことを確かめるでしょう。ここが起きています。あなたがストリームリーダーにストリームを渡すとき、あなたが他の人に使い捨てオブジェクトを与えているが、 "私はまだこれを処分する責任がある、それはあなたのものよりも大きい"と言った場合、それを渡すものはIDisposableを実装する必要さえない。 – Servy

+0

exaがたくさん表示されます後者のmplesとDataContexts。私は、DataContextのインスタンスを取り、Disposableではないヘルパーメソッド/クラスを持っているかもしれません。それはDataContextを破棄しません。DataContextを渡した人は誰でもそれを掃除し、私がまだそれを使用している間は破棄されないことを保証します。 – Servy

3

使い捨てオブジェクトを作成した人物/コード/レイヤーは、一般にオブジェクトを廃棄する必要があります。ただし、これが当てはまらない場合やOKの場合があります。ドキュメンテーションの問題になります。

関連する問題