Wenn ich das Schlüsselwort using
verwende, muss ich noch implementieren IDisposable
?Welche Beziehung besteht zwischen dem Schlüsselwort using und der IDisposable-Schnittstelle?
Antwort
Wenn Sie die using
statement die gekapselten verwenden müssen bereits implementieren IDisposable
sonst wird der Compiler einen Fehler aus. Betrachten Sie daher die IDisposable-Implementierung als Voraussetzung für die Verwendung. Wenn Sie die using
-Anweisung für Ihre benutzerdefinierte Klasse verwenden möchten, müssen Sie IDisposable
dafür implementieren. Dies ist jedoch etwas rückständig zu tun, da es keinen Sinn hat, dies zu tun. Nur wenn Sie etwas wie eine nicht verwaltete Ressource zu entsorgen haben, sollten Sie es implementieren.
// 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
}
}
Dies ermöglicht Ihnen:
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.
effektiv das ist das gleiche wie das Schreiben:
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.
}
Können Sie ein Codebeispiel anzeigen, plz? – Troy
@Troy: Beispiel hinzugefügt, um die Erklärung hervorzuheben. –
Eigentlich ist es ein ziemlich nützliches Muster, wenn Sie einen "Sandwich" -Code haben, der einiges in einem finally-Abschnitt ausführen muss. Ein häufiges Szenario wäre beispielsweise ein Besetzt-Cursor, die Schritte sind ... 1./Kopieren Sie den vorhandenen Cursor 2./setzen Sie den Cursor auf Ihren Warte-Cursor 3./In einem letzten Abschnitt kopieren Sie das Original zurück. Mit einer Verwendung und IDisposable Sie könnten dann Code so etwas wie mit (Busy.WaitCursor) { // Wo Waitcursor ist eine statische Eigenschaft schreiben, die eine Instanz von Besetzt den Konstruktor Kopien und Sätze und die dispose() wieder- kehrt Sätze. } –
Sie sind etwas verwirrend. Sie können das Schlüsselwort using nur für etwas verwenden, das IDisposable implementiert.
Edit: Wenn Sie die Verwendung von Keyword verwenden, müssen Sie Dispose nicht explizit aufrufen, wird automatisch am Ende des using-Blocks aufgerufen werden. Andere haben bereits Beispiele dafür veröffentlicht, wie die using-Anweisung in eine try-finally-Anweisung übersetzt wird, wobei Dispose im finally-Block aufgerufen wird.
Sie können das Schlüsselwort "using" verwenden, wenn Sie Daten aus einem Recordset lesen, richtig? – Troy
@Troy, ja, weil IDataReader IDisposable implementiert. –
Nur wenn alles, was Ihr Recordset umhüllt, IDisposable implementiert. Wenn es kompiliert wird, implementiert es IDisposable .... –
Verwendung wird nur Einweg Objekte entsorgen. Ein Wrapping eines using-Blocks um ein Objekt, das IDisposable nicht implementiert, ist eher nutzlos wird tatsächlich einen Compiler-Fehler verursachen.
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.
In der Tat ist es ein Compilerfehler. – Timwi
Sie nicht das eine ohne das andere haben.
Wenn Sie schreiben:
using(MyClass myObj = new MyClass())
{
myObj.SomeMthod(...);
}
Compiler so etwas wie dies generieren:
MyClass myObj = null;
try
{
myObj = new MyClass();
myObj.SomeMthod(...);
}
finally
{
if(myObj != null)
{
((IDisposable)myObj).Dispose();
}
}
So wie Sie während using
Schlüsselwort mit sehen es wird angenommen,/erforderlich, dass IDisposable implementiert ist.
+1, aber nicht vorausgesetzt - erforderlich. Der Compilercode, den Sie hier gezeigt haben, würde mit einer ungültigen Cast-Ausnahme auskommen, wenn der Typ IDisposable nicht implementiert hat. Dies ist der Grund, warum der Compiler dies verhindert, indem er einen Kompilierzeitfehler gibt, wodurch IDisposable benötigt wird, nicht angenommen wird, um in einer Verwendung verwendet zu werden. –
@Jimmy ja du hast Recht, sagend angenommen ich meinte das. Die Antwort wurde aktualisiert. – Incognito
Ja, die Verwendung von Keyword ist syntaktischer Zucker für diese Art von Muster ... (von Msdn)
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
Edit: ein nützliches Beispiel.
Wenn Sie finden Sie die Dinge in einem endlich Abschnitt consistantly tun, zum Beispiel eines Cursor zurück auf den Standard Zurücksetzen nachdem es auf einen Wartecursor gesetzt zu haben, das ist ein Kandidat für dieses Muster ...
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
}
Genannt wie ...
using(Busy.WaitCursor)
{
// some operation that needs a wait cursor.
}
Die Verwendung von Keyword bereits implementiert, so dass, wenn Sie die Verwendung von Keyword verwenden, müssen Sie nicht IDisposable aufrufen
Sie müssen IDisposable implementieren mit zu verwenden. Wenn Sie versuchen,() auf eine Art zu verwenden, verwenden, die nicht IDisposable nicht implementiert Sie die folgende Kompilierung Fehler:
error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'
Vielleicht, was Sie zu fragen, meine ist: „Wenn ich die‚mit‘Schlüsselwort verwenden, kann ich müssen Sie noch Dispose()? –
Wenn Sie sind, sind Sie bereits. –
@Chris Farmer ... nice edit. Ich fing an zu denken, das ist der neue Müllverdichter von @Apple !!! – user279521