Existem alguns posts que perguntam qual a diferença entre esses dois já.
(Por que eu tenho que mencionar isso ...)
Mas minha pergunta é diferente de uma maneira que estou chamando de "throw ex" em outro método de manipulação semelhante a um deus .
public class Program {
public static void Main(string[] args) {
try {
// something
} catch (Exception ex) {
HandleException(ex);
}
}
private static void HandleException(Exception ex) {
if (ex is ThreadAbortException) {
// ignore then,
return;
}
if (ex is ArgumentOutOfRangeException) {
// Log then,
throw ex;
}
if (ex is InvalidOperationException) {
// Show message then,
throw ex;
}
// and so on.
}
}
Se try & catch
fosse usado no Main
, eu usaria throw;
para repetir o erro. Mas no código simplificado acima, todas as exceções passam porHandleException
Será que throw ex;
tem o mesmo efeito que chamar throw
quando chamado dentro HandleException
?
c#
.net
exception
exception-handling
dance2die
fonte
fonte
Respostas:
Sim, há uma diferença;
throw ex
redefine o rastreamento de pilha (para que seus erros pareçam se originarHandleException
)throw
não - o agressor original seria preservado.fonte
(Publiquei anteriormente e @ Marc Gravell me corrigiu)
Aqui está uma demonstração da diferença:
e aqui está a saída:
Você pode ver que, na exceção 1, o rastreamento de pilha volta ao
DivByZero()
método, enquanto na exceção 2, não.Observe, porém, que o número da linha mostrado em
ThrowException1()
eThrowException2()
é o número da linha dathrow
instrução, não o número da linha da chamadaDivByZero()
, o que provavelmente faz sentido agora que penso um pouco sobre isso ...Saída no modo Release
Exceção 1:
Exceção 2:
Ele mantém o stackTrace original apenas no modo de depuração?
fonte
DevideByZero
, portanto, o rastreamento da pilha é o mesmo. talvez você deva postar isso como uma pergunta por si sóAs outras respostas estão inteiramente corretas, mas acho que essa resposta fornece detalhes adicionais.
Considere este exemplo:
Se você descomentar a
throw arithExc;
linha, sua saída é:Certamente, você perdeu informações sobre onde essa exceção ocorreu. Se, em vez disso, você usar a
throw;
linha, é isso que você obtém:Isso é muito melhor, porque agora você vê que foi o
Program.Div
método que lhe causou problemas. Mas ainda é difícil ver se esse problema vem da linha 35 ou da linha 37 dotry
bloco.Se você usar a terceira alternativa, agrupando uma exceção externa, você não perde nenhuma informação:
Em particular, você pode ver que é a linha 35 que leva ao problema. No entanto, isso requer que as pessoas pesquisem o
InnerException
, e parece um pouco indireto usar exceções internas em casos simples.Em este post eles preservam o número da linha (linha do bloco try) pelo telefone (através da reflexão) o
internal
método intanceInternalPreserveStackTrace()
sobre oException
objeto. Mas não é legal usar reflexões como essa (o .NET Framework pode alterar seusinternal
membros algum dia sem aviso prévio).fonte
vamos entender a diferença entre jogar e jogar ex. Ouvi dizer que, em muitas entrevistas .net, esse pedido comum está sendo solicitado.
Apenas para fornecer uma visão geral desses dois termos, throw e throw ex são usados para entender onde a exceção ocorreu. Throw ex reescreve o rastreamento de exceção da pilha, independentemente de onde realmente foi lançado.
Vamos entender com um exemplo.
Vamos entender primeiro Jogue.
a saída acima está abaixo.
mostra o nome completo do método e da hierarquia onde, na verdade, a exceção foi lançada. é M2 -> M2. junto com os números das linhas
Em segundo lugar .. vamos entender por jogar ex. Apenas substitua o throw pelo throw ex no bloco de captura do método M2. como abaixo.
A saída do código ex throw é a seguinte:
Você pode ver a diferença na saída. Throw ex apenas ignora toda a hierarquia anterior e redefine o rastreamento de pilha com a linha / método em que throw ex é gravado.
fonte
Quando você faz
throw ex
, essa exceção lançada se torna a "original". Portanto, todo o rastreamento de pilha anterior não estará lá.Se você fizer isso
throw
, a exceção simplesmente desce a linha e você obtém o rastreamento completo da pilha.fonte
Não, isso fará com que a exceção tenha um rastreamento de pilha diferente. Somente o uso de um
throw
objeto sem exceção nocatch
manipulador deixará o rastreamento da pilha inalterado.Convém retornar um booleano de HandleException se a exceção deve ser mostrada novamente ou não.
fonte
MSDN significa :
fonte
Veja aqui: http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html
Jogue :
Ele preserva as informações da pilha com exceção
Isso é chamado de "Rethrow"
Se quiser lançar uma nova exceção,
Lançamento Ex :
Ele não envia informações de pilha com exceção
Isso é chamado de "Quebrando a pilha"
Se quiser lançar uma nova exceção,
fonte
Para fornecer uma perspectiva diferente disso, o uso do throw é particularmente útil se você estiver fornecendo uma API a um cliente e desejar fornecer informações detalhadas de rastreamento de pilha para sua biblioteca interna. Usando throw aqui, eu obteria o rastreamento de pilha neste caso da biblioteca System.IO.File para File.Delete. Se eu usar o throw ex, essas informações não serão passadas ao meu manipulador.
fonte
se todas as linhas 1, 2 e 3 forem comentadas - Saída - ex interna
se todas as linhas 2 e 3 forem comentadas - Saída - interna ex System.DevideByZeroException: {"Tentativa de dividir por zero."} ---------
se todas as linhas 1 e 2 forem comentadas - Saída - interna ex System.Exception: devide by 0 ----
se todas as linhas 1 e 3 forem comentadas - Saída - interna ex System.DevideByZeroException: {"Tentativa de dividir por zero."} ---------
e StackTrace será redefinido em caso de throw ex;
fonte