3

例を見てみましょう:

using (var someObject = new SomeObject())
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}

SomeOtherObjectIDisposableも実装します。SomeObjectが破棄されるときに、SomeOtherObjectも破棄されますか?SomeOtherObjectはどうなりますか?(SomeOtherObjectの破棄は、SomeObjectのDisposeメソッドには実装されていません)

4

8 に答える 8

11

いいえ。using句のフィールドのみが破棄されます。あなたの場合はsomeObjectだけです。

基本的に、そのコードはに翻訳されます

var someObject = null;
try
{
  someObject = new SomeObject()

  var someOtherObject = new SomeOtherObject();
  someOtherObject.someMethod(); 
}
finally
{
  if (someObject != null )
  someObject.Dispose()
}
于 2010-03-05T10:42:18.697 に答える
5

いいえ、処分SomeOtherObjectされません。

コードは、コンパイラによって次のように再構築されます。

var someObject = new SomeObject();
try
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}
finally
{
    if (someObject != null)
        someObject.Dispose();
}
于 2010-03-05T10:42:45.573 に答える
5

someOtherObjectは破棄されません。

あなたのコードは次のように変換されます:

var someObject = new SomeObject();
try
{
   var someOtherObject = new SomeOtherObject();
   someOtherObject.someMethod(); 
}
finally
{
    ((IDisposable)someObject).Dispose();
}

したがって、新しく作成されたオブジェクトへの追加の呼び出しは実行されません。

于 2010-03-05T10:44:25.260 に答える
1

MSDNから直接引用:

原則として、IDisposable オブジェクトを使用する場合は、using ステートメントで宣言してインスタンス化する必要があります。using ステートメントは、オブジェクトの Dispose メソッドを正しい方法で呼び出します。また、(前に示したように使用すると)、Dispose が呼び出されるとすぐに、オブジェクト自体がスコープ外になります。using ブロック内では、オブジェクトは読み取り専用であり、変更や再割り当てはできません。

したがって、using ステートメントで宣言およびインスタンス化されたオブジェクトのみが破棄されます。この種の問題については、質問を投稿する前にテストを行うことをお勧めします。

于 2010-03-05T10:45:23.387 に答える
1

someOtherObjectガベージ コレクターによって正常に収集されます。を呼び出す適切なファイナライザ (デストラクタ) を提供しなかった場合Dispose()、これは決して呼び出されません。someObject.Dispose()実行フローがusingブロックを離れるときにのみ呼び出されます。

于 2010-03-05T10:45:31.043 に答える
1

次のように記述します。

using (var someObject = new SomeObject()) {
    using (var someOtherObject = new SomeOtherObject()) {
        someOtherObject.someMethod(); 
    }
}

メソッドが多くの使い捨てオブジェクトを作成している場合、これは手に負えなくなる可能性があります。これは、コードの描画で一般的です。ヘルパー メソッドにリファクタリングするか、明示的な finally ブロックに切り替えます。

于 2010-03-05T12:14:15.603 に答える
0

Disposeによって参照されるオブジェクトのメソッドはsomeObject、コントロールがusingブロックを離れるときに呼び出されます。SuppressFinalizeDisposeメソッドを使用できます。この場合、システムはそのオブジェクトを呼び出しませんfinalizer(そうでない場合は呼び出します)。
ただし、によって参照されたオブジェクトsomeOtherObjectは、適切なタイミングでGCによって収集されます。これは、コントロールがブロックを離れると、どのオブジェクトからも参照されず、収集対象としてマークされるためです。

于 2010-03-05T11:09:22.510 に答える
0

これがあなたの出身地かどうかはわかりません。ブロックのsomeOtherObject外からアクセスすることはできません。スコープ規則usingのため。

using (Stream stream = File.OpenRead(@"c:\test.txt"))
{
   var v1 = "Hello"; //object declared here, wont be accessible outside the block
   stream.Write(ASCIIEncoding.ASCII.GetBytes("This is a test"), 0, 1024);
} //end of scope of stream object; as well as end of scope of v1 object.

v1 = "World!"; //Error, the object is out of scope!

コンパイラ エラー: 「名前 v1 は現在のコンテキストに存在しません。」

以下でもエラーがスローされます。

    {
        int x=10;
    }

    x = 20; //Compiler error: "The name x does not exist in the current context."

詳細については、これこれを参照してください。

于 2010-03-05T12:16:43.507 に答える