2010-04-28 11 views

Odpowiedz

80

Słowo kluczowe "throw" samo w sobie podnosi po prostu wyjątek złapany przez powyższą instrukcję catch. Jest to przydatne, jeśli chcesz wykonać elementarną obsługę wyjątków (być może działanie kompensujące, takie jak wycofanie transakcji), a następnie ponownie zgłosić wyjątek do metody wywołującej.

Ta metoda ma jedną znaczącą przewagę nad wychwyceniem wyjątku w zmiennej i rzuceniem tej instancji: zachowuje oryginalny stos wywołań. Jeśli złapiesz (Exception ex), a następnie wyrzucisz ex, twój stos wywoławczy rozpocznie się dopiero od tej instrukcji throw i stracisz metodę/linię oryginalnego błędu.

+0

Jak rozumiem pytanie, cała zawartość bloku 'catch' to' throw; ', więc nie ma dodatkowej obsługi wyjątków. Może się mylę. – Gorpik

+0

Jaka jest twoja reakcja na punkt Borisa? – CJ7

+0

Boris ma rację, ponieważ podany przykład tak naprawdę nic nie robi, ale nie sądzę, że jest jakakolwiek zmiana w stosie wywołań. –

3

Powtarza dokładnie ten sam błąd, nic nie zyskujesz.
Czasami można użyć metody połowu zrobić kilka rejestrowanie lub coś bez ingerowania w wyjątku tak:

catch (Exception) { 
    myLogger.Log(LogLevels.Exception, "oh noes!") 
    throw; 
} 

początkowo mistakingly myśl ta będzie rozwijać swój stack, ale to będzie tylko wtedy, gdy chcesz wykonać następujące czynności :

catch (Exception err) { 
    throw err; 
} 
+0

Czy jesteś pewien, że masz dodatkowy stos odwijania, ponieważ użycie samego "rzutu" spowoduje ponowne wyrzucenie oryginalnego wyjątku z dokładnym stosem, jak oryginał ... prawda ?! – veggerby

+0

@boris: czy mówisz, że jakiś kod zostanie wykonany dwa razy? – CJ7

+0

@ Veggerby: Masz rację, myliłem się z przypadkiem, w którym mówisz "catch" (Exception ex) {throw ex}. W przypadku kodu pytania nic tak naprawdę nie dzieje się. @Craig: Nic nie zostanie wykonane dwa razy –

3

Jedynym powodem, dla którego mogę myśleć jest to, że chcesz umieścić punkt przerwania podczas debugowania.
To także domyślny kod generowany przez niektóre narzędzia.

11

Czasami chcesz zrobić coś takiego:

try 
{ 
    // do some stuff that could cause SomeCustomException to happen, as 
    // well as other exceptions 
} 
catch (SomeCustomException) 
{ 
    // this is here so we don't double wrap the exception, since 
    // we know the exception is already SomeCustomException 
    throw; 
} 
catch (Exception e) 
{ 
    // we got some other exception, but we want all exceptions 
    // thrown from this method to be SomeCustomException, so we wrap 
    // it 
    throw new SomeCustomException("An error occurred saving the widget", e); 
} 
+2

+1, ponieważ nowy rzut przekazuje oryginalny wyjątek - bardzo, bardzo ważny (-: – Murph

2

Po prostu przekaż bieżący wyjątek i że wyjątek zachowa swoje „źródła” i ślad stosu.