blocos try-catch com o tipo de retorno
-
03-07-2019 - |
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?
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;
}
}