使用キーワードとIDISPOSABLEインターフェイスの関係は何ですか?
-
30-09-2019 - |
質問
私が使用している場合 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.
}
他のヒント
他のものなしでは1つを持つことはできません。
あなたが書くとき:
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が実装されていることが想定されています。
あなたは物事を混乱させています。 idisposableを実装するものに「使用」キーワードのみを使用できます。
編集:使用キーワードを使用する場合、Explake Invoke Disposeを使用する必要がない場合、使用ブロックの最後に自動的に呼び出されます。他の人はすでに、使用ステートメントがどのようにTryに翻訳されるかの例を既に投稿しています - 最終的にステートメントは、最終的なブロック内で廃棄が呼び出されました。
はい、使用するキーワードはこのタイプのパターンの構文砂糖です...(MSDNから)
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
編集:便利な例。
最終的にセクションで一貫して物事を行っていることがわかりました。たとえば、カーソルを待機カーソルに設定した後にデフォルトに戻すなど、これはこのパターンの候補です...
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を実装しないオブジェクトの周りに使用するブロックをラッピングする かなり役に立たない 実際、コンパイラエラーが発生します。
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
原則として、Idisposableオブジェクトを使用する場合、使用するステートメントに宣言してインスタンス化する必要があります。使用されたステートメントは、オブジェクト上の廃棄方法を正しい方法で呼び出し、また、廃棄が呼び出されるとすぐにオブジェクト自体がスコープから外れます。使用ブロック内では、オブジェクトは読み取り専用であり、変更または再割り当てすることはできません。
使用されたステートメントは、オブジェクト上のメソッドを呼び出している間に例外が発生した場合でも、処分が呼び出されることを保証します。オブジェクトをトライブロック内に配置し、最終的にブロックで廃棄することにより、同じ結果を達成できます。実際、これは使用ステートメントがコンパイラによってどのように翻訳されるかです。
使用するために使用するためにidisposableを実装する必要があります。 idisposableを実装していないタイプで()を使用()を使用しようとすると、次のコンパイル時間エラーが表示されます。
error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'
使用キーワードはすでに実装されているため、使用キーワードを使用する場合、Idisposableを呼び出す必要はありません