Pergunta

Se eu tiver um método que retorna algo, como

public DataTable ReturnSomething()
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
   }
}

Isso produz erro do compilador, obviamente, porque bloco catch{} não retorna nada.

Então, quando eu tenho métodos com valores de retorno Não uso bloco try-catch, que é uma prática ruim. Se houver um erro, eu gostaria de definir seqüência de erro para esse erro. Mas então eu preciso de um valor de retorno também. Adendo?

Foi útil?

Solução

Guarde o seu valor de retorno em uma variável temporária como este:

public DataTable ReturnSomething()
{
    DataTable returnValue = null;

    try
    {
        //logic here
        returnValue = ds.Tables[0]; 
    }
    catch (Exception e)
    {
        ErrorString=e.Message;
    }

    return returnValue;
}

Outras dicas

Você deve levantar / lançar a exceção em seu bloco catch e segurá-lo no método de chamada.

public void invokeFaultyCode()
{
    try
    {
        DataTable dt = ReturnSomething();
    }
    catch(Exception e)
    {
        // Print the error message, cleanup, whatever
    }    
}
public DataTable ReturnSomething() throws Exception
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
      throw;
   }
}

PS:. Desculpe por qualquer erro de sintaxe, eu sou um enferrujado bit em C #

Você deve envolver o chamador com um try catch ... quaisquer excepções que acontecem na rotina que é chamada bolha vontade para o chamador e você pode pegá-los lá.

Pessoalmente, eu acho que é um exagero para ter um try catch nessa rotina, como você deve ter o chamador manipular a exceção.

Para o meu exemplo, este seria codificado como segue ...

private void DoSomething() {
    try {
        DataTable dt = ReturnSomething();
    }
    catch (Exception ex) {
    }    
}

public DataTable ReturnSomething() {
    DataTable dt = new DataTable();

    // logic here
    return dt;
}

A variável ErrorString parece suspeito como uma variável de código de erro. A prática recomendada é usar exceções para passar informações de erro diretamente, quando necessário, em vez de armazenar as coisas fora em códigos de erro.

Você está efetivamente fazendo a mesma coisa com o seu ErrorString como você seria se você simplesmente deixar a exceção ser pego pelo chamador: remover a responsabilidade de responder a um erro do próprio método. Esta é uma boa meta de ter. Mas o uso de uma string de erro não ganhar-lhe qualquer coisa sobre o uso de uma exceção. Na verdade, você perde informações desta forma. Há um sem número de tipos de erros que poderiam ocorrer, e muitos têm exceções especiais associados a eles, com suas próprias propriedades especiais para manter informações contextuais sobre a falha. Por apenas armazenar off a mensagem em um String, você está perdendo esta informação.

Assim a menos que seu objetivo é especificamente para esconder o tipo de erro que está ocorrendo a partir do chamador, você só pode ganhar, deixando a exceção completamente.

Outra coisa a considerar é se este é realmente um cenário de erro. Se for, é muito improvável que o seu método de chamada vai cuidado em tudo o que o valor de retorno é. Nesse caso, você não tem nada com que se preocupar por apenas deixando ir exceção e não retornando nada. Se ele não é realmente um cenário de erro, e o chamador está indo só para continuar e fazer outra coisa, bem, isso é o autor da chamada para decidir, certo? Ainda não é muito benefício para obter retornando um string de erro e um manequim DataTable ou um nulo, sobre lançar a exceção com toda a sua contextual informações fracasso.

Se você estiver indo para dirigir o "não jogue uma rota de exceção" (que eu não estou necessariamente reccomending), você pode seguir as TryParse abordagem MS usos.

Algo como:

private string FillDataTable(out DataTable results)
{

  try
{
  results = new DataTable(); //something like this;
  return String.Empty;
}
catch (Exception ex)
{
  results = null;
 return ex.Message;

}

}

Depende de você aplicação. Você pode retornar null, um DataTable vazia ou o que for adequado sob as circunstâncias.

i diria que você ainda pode definir a mensagem, em seguida, retornar nulo ou qualquer que seja o c # equivalente é

public DataTable ReturnSomething(){ 
   try {
        //logic here 
        return ds.Tables[0]; 
   } catch (Exception e) {
        ErrorString=e.Message;
        return null;
   }
}

Como sobre isto:

public DataTable ReturnSomething(out string errorString)
{
   errorString = string.Empty;
   DataTable dt = new DataTable();
   try
   {  
      //logic here
     dt = ds.Tables[0];
   }
   catch (Exception e)
   {
      errorString = e.Message;
   }
   return dt;
}

Uma vez que você está cacthing a exceção (e não jogá-lo novamente) no seu exemplo, o código fora assume everyting é bom e por isso você deve retornar algo útil.

Se você precisa capturar a exceção lá e fazer somthing que é tudo muito bem, mas se é ainda um caso de erro você também deve jogá-lo, ou uma exceção diferente, talvez com o que você acabou de pegar como InnerException.

Eu acho que o código está sendo executado em um nível suficientemente elevado da pilha de chamadas e é misturado com código de UI. Se este for realmente o caso, você poderia return null no bloco catch. No entanto, se você estiver escrevendo código reutilizável, você deve refatorar-lo para que ele não contém manipulação UI e tratar a exceção a um nível superior na pilha de chamadas.

Você pode fazê-lo como o código de exemplo abaixo.

public DataTable ReturnSomething(out string OutputDesc)
{
   try
      {
         //logic here
         OutputDesc = string.Format("Your Successful Message Here...");
         return ds.Tables[0];
      }
      catch (Exception e)
      {
         OutputDesc =e.Message;
         return null;
      }

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top