• ベストアンサー

C# で using

C# で、IDisposable インタフェースを実装したクラスを利用するとき、 SomeClass a = new SomeClass(); (処理) a.Dispose(); のかわりに、 using (SomeClass a = new SomeClass()) {   (処理) } と書くのだと理解しているのですが、例えば SomeClass a = new SomeClass(); SomeClass b = a.SomeMethod(); a.Dispose(); (処理) b.Dispose(); のようなコードを using を用いて書き直すとどのようになるのでしょうか? a, b が、完全なネストになっていないので、こういう場合は無理でしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • JeanneNet
  • ベストアンサー率48% (100/208)
回答No.2

こんにちは、じゃんぬねっと です。 Java の try ~ finally と同じ理論でしょう。 つまり、入れ子に書くべきです。 なるべくすぐ破棄すべきなのですが、大切なのは保証されることです。

migoreng
質問者

お礼

そういうポリシーがあるのですね。 回答、ありがとうございます。

その他の回答 (1)

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

その例の順序をそのまま書き直すのは無理そうですね。 もし「(処理)」の内容が、「(処理)」の前でなく後でa.Dispose();しても問題ないようなものであれば、「(処理)」の場所を移動すればよさそうですが・・・どうしても先にaをdisposeしないとダメな場合ですと、ダメですね。 でも、そんな場合ってあるんでしょうか。

migoreng
質問者

お礼

早速のご回答ありがとうございます。 例えば、 SomeClass a = new SomeClass(); SomeClass b = a.SomeMethod(); a.Dispose(); (処理) SomeClass c = b.SomeMethod(); b.Dispose(); (処理) c.Dispose(); のような状況を考えると、この例では最大でも 2 つのクラス分のメモリしか使用していませんが、 using (SomeClass a = new SomeClass()) {   using (SomeClass b = a.SomeMethod())   {     (処理)     using (SomeClass c = b.SomeMethod())     {       (処理)     }   } } のように書いてしまうと、最大で 3 つのクラス分のメモリを使用することになり、コーディングの都合でリソース解放タイミングが遅れてしまうという状況が発生し、using の趣旨に反することになると思うのです。 よろしくお願いいたします。

migoreng
質問者

補足

すみません。さらに補足いたしますと、 using (SomeClass a = new SomeClass()) {   SomeClass b = a.SomeMethod(); } (bを利用した処理) using (SomeClass c = b.SomeMethod()) {   b.Dispose();   (cを利用した処理) } と書くことは可能だと思います。でも、あまり綺麗ではないですよね。

関連するQ&A

  • C# の using について

    お世話になっております。 C#の using について不明な点がありますので、よろしければご教示願います。 以下のようなサンプルがあったとします。 while の中で、using にてSoapClientに対してコネクションをはって、その後 continue にて途中で抜け出して再度ループを繰り返した場合でも、しっかりと close (Dispose) してくれるのでしょうか。 while (true) {  using (SoapClient client = new SoapClient())  {   client.xxxxx();   continue;  } } using の動作について、はっきりと把握できていないためコードに自信が持てない状態です。 よろしくお願いいたします。

  • C# IDisposable の必要性について

    Visual Studio 2010 を使って C# の勉強をしています。 始めたばかりで質問がおかしかったらすみません。 IDisposable を継承する意味がわかっていません。 MSDN の(http://msdn.microsoft.com/ja-jp/library/fs2xkftw.aspx) 例: 基底クラスの Dispose の実装 にて、 DisposableResourceクラスが IDisposable を継承していますが、 IDisposable を継承する意味はあるのでしょうか? IDisposable がインタフェイスというのは理解していますが、 DisposableResourceクラス の中のpublic void Dispose() は IDisposable を継承しないでも かけるのではないか?と思っています。 恐らく自分の知識が何か抜けていると思うのですが、宜しくお願いします。

  • ClientBase<TChannel> クラスの Dispose() メソッドについて

    お世話になっております。 http://oshiete1.goo.ne.jp/qa5572673.html に引き続き、 Dispose() メソッドの実装について不明な点があるので、よろしければご教示願います。 環境は、Visual C# 2008 Express Edition です。 .NET 3.5 まず、公開されているWebサービスに対して、 ソリューションエクスプローラより、サービス参照の追加で、Clientクラスを自動生成いたしました。 その自動生成されたクラス(仮に XSoapClient)が、System.ServiceModel.ClientBase<TChannel> クラスを継承しています。 ClientBase クラスは、IDisposable インタフェースを実装しているのですが、XSoapClient にも ClientBase にも、Dispose() メソッドの実装が見当たりません。 (自動生成のため、別の場所に作成されているのかもしれません。) using (XSoapClient client = new XSoapClient()) {  // ここにコード } とした場合に、client の Dispose() の実装がわからないため、 しっかりとコネクションが切れているのかが不明です。 Dispose() メソッド内では、Close() メソッドが呼ばれているのが普通なのでしょうか。 以上、よろしくお願いいたします。

  • C# usingの必要性について

    C#について質問させてください。 サブディレクトリにあるcsファイルに記述されているクラスを参照する場合、usingディレクティブでサブディレクトリ名を宣言しないとクラス名のみでの宣言はできませんか? ちょっと伝わりにくいかと思うので、具体例を記載します。 プロジェクト直下にmain.csというファイルとSubというディレクトリがあり、Subディレクトリにsub.csというファイルがあるとします。 main.csのmainメソッドの中でSub s = new Sub();のような記述をしたい場合、using Sub;という記載は(名前空間の解決のために)必要ですか? 私は必要と考えているのですが、usingディレクティブがなくても参照できているコードがありましたので、疑問に思い質問させて頂きました。

  • IDisposableインターフェースの使い方について

    VB2005で開発しています。 インターフェースの勉強をしているのですが、 うまく理解できない部分がありましたので、質問させて頂きました。 IDisposableインターフェースを実装したところ、 Disposeメソッドとその中に GC.SuppressFinalize(Me) という記述が自動で記載されました。 この「GC.SuppressFinalize(Me)」についての質問です。 これはDisposeメソッドを実行した場合は、 明示的にCOMオブジェクトなどの解放処理が行われるため、 ガベージコレクションの機能を実行しなくて良い ということが書かれていると思って良いのでしょうか? そもそもCOMオブジェクトなどは、 明示的に解放しなければ解放できないため、 ガベージコレクションの機能を実行しないことを明示する必要はないのではないか? と疑問に思ってしまったため、質問させて頂きました。 もし宜しければ、ご回答頂けませんか? 宜しくお願い致します。

  • 同一クラスインスタンス名で別クラスのインスタンス作成方法(C++)

    下記ソース(Java)の処理をするような、C++の実装方法を教えていただきたいです。 【処理内容】 クラスBのインスタンスを保持しており、クラスBのインスタンス名と同一であるクラスAのインスタンス生成 ClassA A_Instance = (ClassA)Class.forName(B_instance.name).newInstance(); 要はクラスインスタンスの名前の求め方がわからないのです。それさえわかれば、newしてクラスポインタを返すメソッドを用意すれば何とかなると考えていますが。 ※C++のAPI一覧はどこにあるのだろうか・・・

  • 「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」

    「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」は正しい? はじめまして。Javaのインタフェースに関する質問です。 私はこれまで、インタフェースを使うときは、インタフェースを実装してクラスを宣言し、そのクラス、またはサブクラスでインタフェースがもつすべての抽象メソッドを定義する、と理解していました。 しかし、下の例をみてください。抽象メソッドの定義を、インタフェースの実装の以前で与えています。問題無くコンパイルでき、実行できます。実行結果も以下の通りです。 インタフェースの抽象メソッドへの定義の与え方やその実行のされ方は、メソッドのオーバーライドと同様と思っていましたので、下記のコードでは「クラスBが抽象クラスではありません」や、「インタフェースの抽象メソッドがオーバーライドされていません」などの文法エラーがでると思っていました。 そこで、質問です。 インタフェースが持つ抽象メソッドの定義を与える場所について、または、これに関する説明のあるページなど、何かご存知でしたら教えてください。 ★コード★ interface X{   void show(); } class A{   public void show(){     System.out.println("A");   } } class B extends A implements X{ } public class Main{   public static void main(String[] args){     X x=new B();     x.show();   } } ★実行結果★ >java Main A ★Java環境★ java 1.6.0_21 javac 1.6.0_16

    • ベストアンサー
    • Java
  • c# この高速化の方法あり?

     こんにちは、c#初心者です。  今回は初期化の高速化の方法で悩んでいるので質問させていただきました。  ライブラリ内でstrring型と同じくらい頻繁に初期化が行われる使い方をされるクラスAを作り、そこからクラスBへ、クラスBからクラスCへ…クラスEといった感じで継承させています。  ところが、どのクラスもクラスAと同じように頻繁に新しいインスタンスが初期化されるのでコンストラクタの処理時間が一部のパフォーマンスに結構ひびくのですが、継承しているために、クラスCを初期化するだけで、クラスAとクラスBのコンストラクタが呼び出されてしまい、このことが特にクラスEではきついのです。  確かに呼び出しに取られる時間は少ないとはいえ、もともとコンストラクタでの作業は少ないので、割合としてはそこそこな時間を取っている状態になっています。  そこで思いついたのが、インターフェイスを利用して継承を使わないという方法です。  それぞれ、IA, IB, …, IEで対応するインターフェイスを実装。例えばクラスBはIA, IBの二つ、クラスEはIA~IE全てのインターフェイスを実装している状態です。  他に思いついたのは、上記の方法+クラスB以降を全てクラスAから派生させるという方法です。速度は満点ではありませんが、これならある程度抽象化もできて、余分なコンストラクタ呼び出しも1回で済みます。  ちなみにこれは現在製作中のライブラリ内で使われているクラスです。末端のアプリケーションなら問題ないような気がするのですが、何しろライブラリなのでこんな手法は如何かと思い質問させていただきました。  自分が見る限りではコンストラクタ内に他に余分なコードはありませんし、無論ループはありませんが、他に高速化する方法があればそれも教えていただきたいです。  とりあえず、言語の性能を最大限に引き出すことでの高速化をコンセプトにしているので多言語への乗り換えは無しということでお願いします。

  • singletonによるインターフェイスの実装

    Java勉強中の初心者です。 標題の件についてお願いします。 以下、簡単に条件を説明させていただきます。 Aクラス = メインクラス Bクラス = インターフェイスクラス Cクラス = DとEを動的に生成するクラス Dクラス = インターフェイスを実装するクラス Eクラス = インターフェイスを実装するクラス AクラスにB.getInstance(name)があります。 for文の無限ループがあります。 Cクラス class C { public static B getInstance(String name) { // Aクラスのaと変数nameが比較して一致したら // Dクラスのインスタンス生成 // 一致しなかったらEクラスのインスタンス生成 if(A.a.equals(name)){ return D.getInstance(); }else{ return E.getInstance(); } } } Dクラス class D implements B{ private D() { } public static D getInstance() { D d = new D(); return d; } // インターフェイスでのメソッド省略します。 } Eクラス class E implements B{ private E() { } public static E getInstance() { E e = new E(); return e; } // インターフェイスでのメソッド省略します。 } この条件の時にnewするたびにインスタンスが 生成されてしまいます。 インスタンスの生成が一度だけしか 生成されないようにするには、C,D,Eクラスで どのように記述すればいいか悩んでいます。 (骨組みは書けましたが) クラスを簡単に省略してわかりづらいと 思いますがよろしくお願いします。

    • ベストアンサー
    • Java
  • C#のusing文でメソッドの戻り値にオブジェクト

    C#4.0を使用しています。 例えば、次のようなメンバやメソッドの戻り値がオブジェクトを返す場合に、 usingの()の中で記述した時に確実にリソースを解放してくれるのでしょうか? そもそもこのような使い方(メソッドがオブジェクトを返す)をして良いのでしょうか? public class SQLiteAdapter {  public DbConnection Connection  {   get { return new SQLiteConnection("Data Source=test.db"); }  } } adapter = new SQLiteAdapter(); using (DbConnection conn = adapter.Connection) { } なぜこのようなことをやりたいと思ったかというと、 SQLiteやMySqlの共通のラッパークラスのようなものを作りたいと思いました。 ただほとんどの処理の構造は同じなので、 違う部分だけをメソッドの戻り値で済ましたいと思いました。 例えばDbConnectionの場合、 SQLiteならSQLiteConnection MySqlならMySqlConnection 例えばクエリを実行する処理では public Boolean ExecuteNonQuery(string sql) { SQLiteTransaction tx = null; using (SQLiteConnection conn = new SQLiteConnection(this.connectionString)) using (SQLiteCommand cmd = conn.CreateCommand()) { try { conn.Open(); //トランザクション開始 tx = conn.BeginTransaction(); cmd.CommandText = sql; cmd.Transaction = tx; //SQL実行 cmd.ExecuteNonQuery(); //コミット tx.Commit(); return true; } catch (Exception ex) { //ロールバック if (tx != null) tx.Rollback(); return false; } finally { } } } SQLiteTransaction、SQLiteCommand、SQLiteConnection の3箇所をMySqlなら MySqlTransaction、MySqlCommand、MySqlConnection に変更すればいいわけですよね? なのでそれぞれのアダプター側でこのように同じような処理を書かずに 基本クラス側で処理を記述し、各派生クラス側ではリソース(オブジェクト)を返すメソッド を用意すればいいのかな?と思いました。 ただ質問のようなusing文の使い方で大丈夫なのか疑問に思って質問しました。 よろしくお願いします。