2009-03-17 17 views
0

Ich sehe eine Menge Code-Schnipsel mit der folgenden SyntaxWelchen Sinn hat die Verwendung von Blöcken im C# -Code?

using (RandomType variable = new RandomType(1,2,3)) 
{ 
    // A bunch of code here. 

} 

warum nicht nur die Variable deklarieren und es verwenden?

Diese Using-Syntax scheint den Code nur unübersichtlich zu machen und ihn weniger lesbar zu machen. Und wenn es so wichtig ist, dass diese Variable nur in diesem Bereich verfügbar ist, warum sollte man diesen Block nicht in eine Funktion einfügen?

+0

Dup von http://stackoverflow.com/questions/75401/uses-of-using-in-c und http://stackoverflow.com/questions/561354/what-is-the-purpose-of-using –

+2

Es scheint nur nutzlos, wenn Sie nicht wissen, was es tut. – recursive

+0

Ist es wirklich zu viel, F1 auf das using-Schlüsselwort zu drücken? – Andy

Antwort

11

Verwendung hat einen sehr unterschiedlichen Zweck.

Es wurde für die Verwendung mit Typen entwickelt, die IDisposable implementieren.

In Ihrem Fall, wenn RandomType IDisposable implementiert, wird es erhalten .Dispose() 'd am Ende des Blocks.

+0

Wenn es IDisposable nicht implementiert, glaube ich nicht, dass es tatsächlich kompilieren wird. – Svish

+0

Tatsächlich wird ein Kompilierungsfehler auftreten. –

+0

Sie können jedoch nichts als IDisposable in der Verwendung von ... (SomeType als IDisposable). Wenn SomeType IDisposable nicht implementiert, wird NULL übergeben und nie entfernt, was sicher ist. –

9
using (RandomType variable = new RandomType(1,2,3)) 
{ 
    // A bunch of code here. 
} 

ist so ziemlich das gleiche (mit einem paar feinen Unterschieden) als:

RandomType variable = new RandomType(1,2,3); 

try 
{ 
    // A bunch of code 
} 
finally 
{ 
    if(variable != null) 
     variable.Dispose() 
} 

Beachten Sie, dass, wenn "Verwendung" zu nennen, können Sie alles als IDisposable werfen können:

using(RandomType as IDisposable) 

Der Null-Check im finally wird alles fangen, was IDisposable nicht implementiert.

+0

Nicht ganz: 'using' beschränkt auch den Namen "varialbe" auf den Gültigkeitsbereich des using-Blocks, sodass Sie diesen Namen in einer anderen Deklaration im selben Gültigkeitsbereich wiederverwenden können. Aber das Wesentliche ist da. –

+0

Antwort hinzugefügt mit korrektem "ziemlich genau dasselbe wie" laut MSDN. – Svish

+0

@Joel Sie haben Recht, aber dies wird vom C# -Compiler erzwungen. In IL wird das RandomType-Objekt außerhalb des try-Blocks erstellt. @Brian Eigentlich ist das check im finally Block if (variable! = Null). Mit dem C# -Compiler können Sie nicht verwenden, wenn RandomType IDisposable nicht implementiert. –

1

Ein Objekt, das in einer using-Anweisung verwendet wird, muss IDisposable implementieren, damit am Ende des Bereichs garantiert ist, dass Dispose() aufgerufen wird. Daher sollte Ihr Objekt theoretisch zu diesem Zeitpunkt freigegeben werden. In einigen Fällen habe ich festgestellt, dass es meinen Code klarer macht.

4

Nein, es macht den Code nicht unübersichtlich oder weniger lesbar.

Eine using-Anweisung kann nur für IDisposable-Typen verwendet werden (dh Typen, die IDisposable implementieren).

Wenn Sie diesen Typ in einen using - Block eingeben, wird die Dispose - Methode dieses Typs verwendet, wenn der Gültigkeitsbereich des using - Blocks endet.

mir also sagen, welcher Code für Sie weniger lesbar ist:

using(SomeType t = new SomeType()) 
{ 
    // do some stuff 
} 

oder

SomeType t = new SomeType(); 

try 
{ 
    // do some stuff 
} 
finally 
{ 
    if(t != null) 
    { 
     t.Dispose(); 
    } 
} 
+0

Eigentlich diese beiden Methoden zu Unordnung hinzufügen - es ist nur, dass es derzeit keine bessere Option als "verwenden". Zu viele Blöcke (oder try..finally blocks) führen zu einer Code-Einrückung und Einschränkungen, wo Objekte erstellt oder disponiert werden (z. B. kann man nicht mit Blöcken staffeln). – mbeckish

1

Die Verwendung von Keyword eine deterministische Art und Weise liefert allocates die verwalteten oder nicht verwalteten Ressourcen zu bereinigen, dass ein Objekt . Wenn Sie das Schlüsselwort using nicht verwenden, müssen Sie Dispose() (oder in einigen Fällen Close()) aufrufen, wenn Sie mit diesem Objekt fertig sind. Andernfalls werden die Ressourcen möglicherweise nicht bis zur nächsten Speicherbereinigung oder gar nicht bereinigt.

1

Nach MSDN, die folgende using Code:

using (Font font1 = new Font("Arial", 10.0f)) 
{ 
    byte charset = font1.GdiCharSet; 
} 

dazu erweitert:

{ 
    Font font1 = new Font("Arial", 10.0f); 
    try 
    { 
    byte charset = font1.GdiCharSet; 
    } 
    finally 
    { 
    if (font1 != null) 
     ((IDisposable)font1).Dispose(); 
    } 
} 

Und es ist wirklich nicht der Code Krempel. Ganz im Gegenteil!

Verwandte Themen