2011-08-26 8 views
12

Czy jedno z tych ryzykownych jest ryzykowne? Czy jest lepszy? A może to jedna z tych rzeczy, które wydrukujesz i rzucasz strzałką, aby zdecydować?Powrót w try & catch a zwrot w końcu?

chcę to zrobić teraz, kiedy wreszcie zrozumieć, jak działa:

try { 
    stuff that changes something... 
} 
catch (System.Exception ex) { 
    something.worked = false; 
    something.err = ex.Message; 
} 
finally { 
    stuff.close(); 
    return something; 
} 

Ale widziałem:

try { 
    stuff that changes something... 
    return something; 
} 
catch (System.Exception ex) { 
    something.worked = false; 
    something.err = ex.Message; 
    return something; 
} 
finally { 
    stuff.close(); 
} 
+1

@ Dlev - Z wyjątkiem pierwszego nie jest prawidłowym C#, więc nie można tego zrobić. Więc jak to może być lepsze? To pytanie powinno zostać ponownie zadane, gdzie każdy kod jest rzeczywiście prawidłowym kodem, w przeciwnym razie jest bezsensowny. –

+0

@Ramhound Oops, chodzi mi o to, że ten pierwszy nie jest legalny C#. Ta ostatnia jest rzeczywiście poprawna składniowo. – dlev

Odpowiedz

17

nie może return z finally Ty. otrzymasz błąd kompilatora:

Control cannot leave the body of a finally clause


Jeśli klasa cel realizuje IDisposable to bym dalej:

using (stuff s = new stuff()) 
{ 
    return stuff; 
} 

lub

using (stuff s = new stuff()) 
{ 
    try 
    { 
     // do stuff 
     return stuff; 
    } 
    catch (Exception ex) 
    { 
     // do logging or another stuff 
     return something; 
    } 
} 

wezwie Dispose() dla ciebie jeśli wola być wymagane/możliwe.

+0

Doh! Spróbuj skompilować zanim zapytasz następnym razem, Self! To ma sens, że kontrola nie może opuścić w końcu, ponieważ w końcu jest tak wyjątkowa w wymagającej uwagi. – ChuckNeuros

+2

@ user540903: Tak, powinieneś go skompilować. Ale nie bój się zbyt mocno; istnieją języki, w których zwrot z wreszcie jest legalny, a te języki mają w rezultacie jakąś dość dziwną semantykę sterowania przepływem. Jest to uzasadnione pytanie w ogóle, po prostu nie dla C#. –

+0

@Eric I'm pretty Java jest jednym z tych języków. Z tego co pamiętam, ostatnie 'return' nadpisuje poprzednie, więc' try {throw new BlahException(); } catch {return 1; } finally {return 2; } 'faktycznie zwraca' 2' do wywołującego. – dlev

17

Osobiście chciałbym zrobić i nie użyłby


try { 
    stuff that changes something... 
} 
catch (System.Exception ex) { 
    something.worked = false; 
    something.err = ex.Message; 
} 
finally { 
    stuff.close();  
} 
return something; 

również w rachunku finally sprawdzić, że trzeba zamknąć/wyrzucać przedmiotów, gdyż może nigdy nie zostały otwarte/set gdyby zawiodły.

patrz także tutaj Is it bad practice to return from within a try catch finally block?

+1

Zgadzam się z tym, ponieważ abatishchev mówi, że nie możesz wrócić w końcu, nie sądzę, że powinieneś wrócić w haczyku. Jeśli próbujesz złapać i nie powracasz, chcesz, aby powrócił w każdy sposób, a jeśli powrócisz, to i tak nigdy nie wróci. Tak czy inaczej potrzebujesz tylko 1 zwrotnego oświadczenia, a nie 2 –

+1

powrót z próby/catch/finally nie jest uważany za "programowanie strukturalne". Zgadzam się z Timem i Benem. –

0

Nie ma ryzyka w drugim podejściu. Ale pozwala zwracać różne wartości w przypadku wyjątków.

+1

Tak więc zwraca zmienną i ustawia ją na różne wartości w blokach try i catch, ale tylko mając 1 powrót poza całym blokiem try/catach. –

+0

zwracanie wartości zmiennej umożliwiłoby również zwracanie różnych wartości w przypadku wyjątków. –