C# 
- Diferença entre throw e throw ex
    
    
    ![]()  | 
    Apresentando as diferenças entre throw e throw ex no tratamento de exceções na linguagem c#. | 
Quando tratamos exceções na linguagem C# geralmente usamos o bloco try/catch/finally e podemos encontrar diversos exemplos que usam duas abordagens :
		 try
 {
    //algum código
 }
 catch
 {
    throw;
 }
		 | 
		
		 try
 {
    //algum código
 }
 catch (Exception ex)
 {
     throw ex;
 }
		 | 
	
Vamos entender o que acontece em cada abordagem:
1 - lançando um throw
Quando você lança apenas um throw está repassando a mesma exceção para frente e, dessa forma, outro trecho de código poderá capturar e saber o que vai fazer com a exceção original retendo todas as informações necessárias com o stack trace.
2 - lançando um throw ex
Quando você lança um throw ex, você esta parando a exceção ali e após fazer alguma operação, você lança outra exceção a partir dali. Dessa forma a informação de onde veio a exceção original é perdida. Tudo se passa como se tivesse ocorrido uma nova exceção.
Agora vamos usar um exemploprático para você perceber como isso é importante e porque você deve dar preferência usar a primeira opção.
Recursos Usados neste artigo :
Criando o projeto Console
Crie um projeto Console Application e inclua o seguinte código no arquivo Program.cs :
1 - lançando um throw
		using System;
		namespace CShp_Exceptions
{
    class Program
    {
        static void Main(string[] args)
        {
            Funcionario funci = new Funcionario();
            Console.WriteLine(funci.GetDetalhes());
            Console.Read();
        }
		        class Funcionario
        {
            public String GetDetalhes()
            {
                try
                {
                    Departamento depto = new Departamento();
                    return depto.GetDepartmentos();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("---Registra Stack Trace para exceções----");
                    Console.WriteLine(ex.StackTrace.ToString());
                    Console.WriteLine("---Registra o nome do método na qual a exceção ocorreu---");
                    Console.WriteLine(ex.TargetSite.ToString());
                }
                return "";
            }
        }
        class Departamento
        {
            public String GetDepartmentos()
            {
                try
                {
                    DividirPorZero();
                    return "Método GetDepartmentos foi chamado";
                }
                catch(Exception ex) 
                {
                    throw;
                }
            }
            //estamos gerando uma exception 
            public void DividirPorZero()
            {
                throw new DivideByZeroException();
            }
        }
    }
}
		 | 
	
Neste código estamos gerando uma exceção do tipo divisão por zero e usando um try/catch lançado apenas throw.
Veja o resultado obtido:

Observe que todos os métodos foram registrados na pilha; inclusive o método DividirPorZero() que causou a exceção.
2 - lançando um throw ex
		using System;
		namespace CShp_Exceptions
{
    class Program
    {
        static void Main(string[] args)
        {
            Funcionario funci = new Funcionario();
            Console.WriteLine(funci.GetDetalhes());
            Console.Read();
        }
		        class Funcionario
        {
            public String GetDetalhes()
            {
                try
                {
                    Departamento depto = new Departamento();
                    return depto.GetDepartmentos();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("---Registra Stack Trace para exceções----");
                    Console.WriteLine(ex.StackTrace.ToString());
                    Console.WriteLine("---Registra o nome do método na qual a exceção ocorreu---");
                    Console.WriteLine(ex.TargetSite.ToString());
                }
                return "";
            }
        }
        class Departamento
        {
            public String GetDepartmentos()
            {
                try
                {
                    DividirPorZero();
                    return "Método GetDepartmentos foi chamado";
                }
                catch(Exception ex) 
                {
                    throw ex;
                }
            }
            //estamos gerando uma exception 
            public void DividirPorZero()
            {
                throw new DivideByZeroException();
            }
        }
    }
}
		 | 
	
Neste código apenas alteramos o bloco try/catch e agora estamos lançando um throw ex.
Veja o resultado:
		![]()  | 
	
Analisando a pilha exibida na figura acima note que apenas os métodos GetDepartamentos e GetDetalhes foram gravados na pilha.
O método DividirPorZero() que foi a causa da exceção não foi gravado na pilha.
Como usamos throw ex no método GetDepartamentos a pilha removeu o DividirPorZero() da pilha.
Concluimos assim que throw mantém a hierarquia de exceções no rastreamento da pilha e fornece informações completas enquanto que throw ex retorna as exceções até o ponto no qual o código throw ex foi excecutado, ai, ele remove os detalhes da exceção ate este ponto.

Entendeu agora por que dar preferência a lançar apenas throw ?
(disse 
Jesus) "Eu sou o 
pão vivo que desceu do céu; se alguém comer deste pão, viverá para sempre; e o 
pão que eu der é a minha carne, que eu darei pela vida do mundo. "
João 6:51
Referências: