using
キーワードを使用している場合でも、実装する必要がありますIDisposable
か?
7 に答える
あなたはもう一方なしで一方を持つことはできません。
あなたが書くとき:
using(MyClass myObj = new MyClass())
{
myObj.SomeMthod(...);
}
コンパイラは次のようなものを生成します:
MyClass myObj = null;
try
{
myObj = new MyClass();
myObj.SomeMthod(...);
}
finally
{
if(myObj != null)
{
((IDisposable)myObj).Dispose();
}
}
したがって、キーワードを使用しているときにわかるようにusing
、IDisposableが実装されていると想定/必須です。
using
ステートメントを使用する場合、囲まれた型はすでに実装されている必要がIDisposable
あります。そうでない場合、コンパイラーはエラーを発行します。したがって、IDisposableの実装を使用の前提条件と見なしてください。
using
カスタムクラスでステートメントを使用する場合は、それを実装する必要がありますIDisposable
。しかし、それのためにそうする意味がないので、これはやや逆行です。管理されていないリソースのように処分するものがある場合にのみ、それを実装する必要があります。
// To implement it in C#:
class MyClass : IDisposable {
// other members in you class
public void Dispose() {
// in its simplest form, but see MSDN documentation linked above
}
}
これにより、次のことが可能になります。
using (MyClass mc = new MyClass()) {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
} // Here the .Dispose method will be automatically called.
事実上、それは書くことと同じです:
MyClass mc = new MyClass();
try {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
}
finally { // always runs
mc.Dispose(); // Manual call.
}
あなたは物事を混乱させています。「using」キーワードは、IDisposableを実装するものにのみ使用できます。
編集:usingキーワードを使用する場合、明示的にDisposeを呼び出す必要はありません。これは、usingブロックの最後で自動的に呼び出されます。他の人は、usingステートメントがどのようにtry-finallyステートメントに変換され、finallyブロック内でDisposeが呼び出されるかの例をすでに投稿しています。
はい、usingキーワードはこのタイプのパターンのシンタックスシュガーです...(msdnから)
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
編集:便利な例。
たとえば、カーソルを待機カーソルに設定した後でデフォルトにリセットするなど、finallyセクションで一貫して作業を行っていることがわかった場合、これはこのパターンの候補です...
public class Busy : IDisposable
{
private Cursor _oldCursor;
private Busy()
{
_oldCursor = Cursor.Current;
}
public static Busy WaitCursor
{
get
{
Cursor.Current = Cursors.WaitCursor;
return new Busy();
}
}
#region IDisposable Members
public void Dispose()
{
Cursor.Current = _oldCursor;
}
#endregion
}
のように呼ばれる...
using(Busy.WaitCursor)
{
// some operation that needs a wait cursor.
}
使用すると、使い捨ての物体のみが処分されます。したがって、IDisposableを実装していないオブジェクトの周りにusingブロックをラップすることは、実際にはコンパイラエラーを引き起こします。
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
原則として、IDisposableオブジェクトを使用する場合は、usingステートメントで宣言してインスタンス化する必要があります。usingステートメントは、オブジェクトのDisposeメソッドを正しい方法で呼び出します。また、Disposeが呼び出されるとすぐに、オブジェクト自体がスコープ外になります。usingブロック内では、オブジェクトは読み取り専用であり、変更または再割り当てすることはできません。
usingステートメントは、オブジェクトのメソッドの呼び出し中に例外が発生した場合でも、Disposeが呼び出されるようにします。オブジェクトをtryブロック内に配置し、finallyブロックでDisposeを呼び出すことで、同じ結果を得ることができます。実際、これはusingステートメントがコンパイラーによって変換される方法です。
usingキーワードはすでに実装されているため、usingキーワードを使用する場合は、IDisposableを呼び出す必要はありません。
を使用するには、IDisposableを実装する必要があります。IDisposableを実装していない型でusing()を使用しようとすると、次のコンパイル時エラーが発生します。
error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'