2013-01-31 19 views
6

Powiel możliwe:
Nested using statements in C#Czy można używać `use` w ten sposób?

Jestem wielkim fanem rachunku w C# using. Uważam to:

using (var foo = new ObjectWhichMustBeDisposed()) 
{ 
    other code 
} 

... bardzo dużo bardziej czytelny niż ten:

var foo = new ObjectiWhichMustBeDisposed(); 

try 
{ 
    other code 
} 
finally 
{ 
    foo.Dispose(); 
} 

Nie tylko jest to bardziej czytelne, ale również zapobiega przypadkowym użyciem zmiennej foo po oświadczeniu using (tj po jego usunięciu), podczas gdy w drugim przykładzie można użyć foo po jego usunięciu.

Jednym z problemów z using jest jednak to, że prowadzi to do bardzo zagnieżdżonego kodu, jeśli tworzonych jest wiele obiektów jednorazowego użytku. Na przykład:

using (var foo = new ObjectWhichMustBeDisposed()) 
{ 
    using (var bar = new ObjectWhichMustBeDisposed()) 
    { 
     other code 
    } 
} 

Jeżeli oba obiekty są tego samego typu, a następnie można je połączyć w jeden using oświadczeniu tak:

using (var foo = new ObjectWhichMustBeDisposed(), 
      bar = new ObjectWhichMustBeDisposed()) 
{ 
    other code 
} 

Jednakże, jeśli obiekty nie są z ten sam typ, to nie zadziała.

Moje pytanie brzmi, czy jest to OK, aby osiągnąć podobny koniec takiego:

using (var foo = new ObjectWhichMustBeDisposed()) 
using (var bar = new OtherObjectWhichMustBeDisposed()) 
{ 
    other code 
} 

W tym przypadku nie ma kręcone szelki po pierwszym użyciu (a więc nie ma potrzeby, aby wciąć kod). To kompiluje, a I zakłada, że działa to tak jak instrukcja if bez żadnych nawiasów klamrowych - to znaczy użyje następnego oznaczenia (w tym przypadku drugiego using) jako swojego "ciała".

Czy ktoś może potwierdzić, czy to prawda? (The description of the using statement nie jest pomocny).

+0

To na pewno działa. Jeśli jest OK, to między tobą a twoim stylem kodowania. – CodesInChaos

+0

Tak, to jest całkowicie poprawne :) –

+0

Kompiluje dobrze, jedyne co powiedziałbym to to, że dla czytelności i spójności trzymam się stylu owijania bloków kodu wokół '{}' – MethodMan

Odpowiedz

2

Spójrz na using definicji rachunku w standardzie C#:

12.3.3.17 użyciu instrukcji
Za pomocą instrukcji instr formularza:
korzystania z zasobów (pozyskania) osadzony-oświadczenie

Osadzone oświadczenie jest cokolwiek z poniższych (patrz element A2.5):

osadzony-oświadczenie:
blok
pustymi oświadczenie
wyrażenie-oświadczenie
wybór-oświadczenie
iteracja-oświadczenie
jump-oświadczenie
try-oświadczenie
zameldowaliśmy oświadczenie
niezaznaczone oświadczenie
blokady stwierdzenie
pomocą instrukcja_select
wydajność instrukcja_select

więc zarówno zwyczaje using (blok lub innej przy instrukcja_select) są całkowicie równoważne C# standardowego punktu widzenia.

+0

Dziękuję wszystkim, którzy odpowiedzieli i przepraszam, nie mogę przyjąć was wszystkich, ale pomyślałem, że lepiej zaakceptować tę odpowiedź - która jest ostateczna/poparta dowodami. –

7

Tak kod proponujesz

using (var foo = new ObjectWhichMustBeDisposed()) 
using (var bar = new OtherObjectWhichMustBeDisposed()) 
{ 
    other code 
} 

jest zarówno OK i dość powszechne.

Nie trzeba używać dodatkowego {} po każdym wykorzystaniem (innego niż ten, który zawiera inny kod, jeśli inny kod jest więcej niż jeden rachunek), ponieważ każdy z użyciem ma dokładnie jedno oświadczenie następującej go .

using (var foo = new ObjectWhichMustBeDisposed()) 
using (var bar = new OtherObjectWhichMustBeDisposed()) 
using (var baz = new OtherObjectWhichMustBeDisposed()) 
using (var quux = new OtherObjectWhichMustBeDisposed()) 
{ 
    other code 
} 

będzie również w porządku.

+1

Dotyczy to również instrukcji strukturalnych, takich jak 'if',' while' itd. –

+0

@ OlivierJacot-Descombes Z wyjątkiem 'try' /' catch'.[Oto dlaczego] (http://ericlippert.com/2012/12/04/why-are-braces-required/) – Servy

1

Tak, to prawda.

using (var foo = new ObjectWhichMustBeDisposed()) 
using (var bar = new OtherObjectWhichMustBeDisposed()) 
{ 
    other code 
} 

Reszta należy do Ciebie. Jeśli podoba ci się ten sposób kodowania, idź z nim.

Powiązane problemy