2010-10-15 14 views
14

Byłem patrząc na użyciu w C# i chcę wiedzieć, czy poniższy kod jest równoważny;Różne sposoby używania Użycie W C#

using (SqlConnection connection1 = new SqlConnection(), connection2 = new SqlConnection()) 
{ 
} 

Do tego kodu;

using (SqlConnection connection1 = new SqlConnection()) 
using (SqlConnection connection2 = new SqlConnection()) 
{ 
} 
+0

Powiedziałbym, że są takie same, ale mogę się mylić ... ale możesz to przetestować. – Nate

+9

Osobiście uważam, że drugi jest łatwiejszy do odczytania. – Bryan

+0

Te dwie są równoważne. Zobacz następujące pytanie SO: http://stackoverflow.com/questions/1329739/nested-using-statements-in-c –

Odpowiedz

27

C# Spec mówi

Gdy zasobów przejęcie przybiera formę lokalnej zmiennej-deklaracji, możliwe jest nabywać wielokrotność zasobów danego typu. A, stosując zestawienie postaci

using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement 

jest właśnie odpowiednikiem sekwencji zagnieżdżonych sprawozdania Zastosowanie:

using (ResourceType r1 = e1) 
     using (ResourceType r2 = e2) 
      ... 
      using (ResourceType rN = eN) 
       statement 
5

Tak, te dwie części kodu są równoważne.

Edytuj

Właśnie to przetestowaliśmy z reflektorem. Dokładnie takie same IL emitowane dla dwóch wersji, a reflektor decompiles do następującego: C#:

using (new SqlConnection()) 
{ 
    using (new SqlConnection()) 
    { 
    } 
} 

Oznacza to, że dla obu wersji, usunąć będzie wykorzystywana w obydwu przypadkach, nawet jeśli jeden zgłasza wyjątek konstruktora.

3

Tak, są dokładnie takie same. Możesz użyć Reflectora, aby to udowodnić.

public void Method1() 
    { 
     using (SqlConnection connection1 = new SqlConnection()) 
     using (SqlConnection connection2 = new SqlConnection()) 
     { 
     } 
    } 

    public void Method2() 
    { 
     using (SqlConnection connection1 = new SqlConnection(), connection2 = new SqlConnection()) 
     { 
     } 
    } 
7

Można oczywiście wstawić jakiś kod między pierwszym i drugim użyciu, że używa połączenia1 przed utworzeniem połączenia2.

Ale ty nie, tak jak nie ma żadnej różnicy. Obaj wytworzenia tej samej IL:

IL_0000: newobj  System.Data.SqlClient.SqlConnection..ctor 
IL_0005: stloc.0  
IL_0006: newobj  System.Data.SqlClient.SqlConnection..ctor 
IL_000B: stloc.1  
IL_000C: leave.s  IL_0018 
IL_000E: ldloc.1  
IL_000F: brfalse.s IL_0017 
IL_0011: ldloc.1  
IL_0012: callvirt System.IDisposable.Dispose 
IL_0017: endfinally 
IL_0018: leave.s  IL_0024 
IL_001A: ldloc.0  
IL_001B: brfalse.s IL_0023 
IL_001D: ldloc.0  
IL_001E: callvirt System.IDisposable.Dispose 
IL_0023: endfinally 
5

Tak, według section 8.13 of the C# Language Specification:

Gdy zasobów przejęcie przybiera formę lokalnej zmiennej-deklaracji, możliwe jest nabywać wielokrotność zasoby danego typu.A, stosując instrukcji postaci

using (ResourceType r1 = e1, r2 = e2, ..., rN = eN)

stwierdzenie dokładnie równoważny z sekwencją zagnieżdżone użyciu instrukcji:

using (ResourceType r1 = e1)
using (ResourceType r2 = e2)
...
using (ResourceType rN = eN)
        rachunku

1

Oprócz doskonałej wzmianek o C# 8.13 innych odpowiedzi, w przypadku pojedynczej klauzula będzie musiał zostać przepisany, gdy jeden z zasobów musi zmienić typ.

using(S r1 = new S(), r2 = new S()) 
{ 
    ... 
} 

Kiedy r2 musi być zmieniony w nowego typu, to musi stać

using(S r1 = new S()) 
using(T r2 = new T()) 
{ 
    ... 
} 

Więc jesteś lepiej z użyciem tego ostatniego. (Osobiście uważam, że to też lepiej czyta)

Powiązane problemy