Pergunta

Aqui está uma pergunta para expor minha falta de experiência: Eu tenho um método DoSomething () que gera uma exceção se ele não conseguir fazê-lo de forma limpa. Se ele falhar, eu tento o método menos preciso DoSomethingApproximately () várias vezes na esperança de que ele vai encontrar uma suficientemente boa solução; Se isso também falhar eu finalmente chamar DoSomethingInaccurateButGuaranteedToWork () . Todos os três são métodos que pertencem a este objeto.

Duas perguntas:? Primeiro, é este (reconhecidamente feio) padrão aceitável, ou se existe uma maneira mais elegante

Em segundo lugar, qual é a melhor maneira de manter o controle de quantas vezes eu tenho chamado DoSomethingApproximately () , dado que é provável que lançar uma exceção? Atualmente, estou mantendo um iNoOfAttempts variáveis ??no objeto, e blocos try nidificação ... isso é horrível e eu me envergonho.

Foi útil?

Solução

Você nunca deve usar exceções para o fluxo de sua aplicação de controle.

No seu caso eu tinha bando os três métodos em um único método e tê-lo retornar qual abordagem particular, conseguiu, talvez com uma enumeração ou algo parecido.

Outras dicas

retornar um código de erro em vez de lançar uma exceção.

Se as maneiras esses métodos falham fazer exceções lance, pegá-los todos no mesmo método e tomar medidas adequadas, como aumentar um contador e retornar um código de erro.

   bool result = DoSomething();
   while (!result && tries < MAX_TRIES) {
       result = DoSomethingApproximately(); //This will increment tries
       if (tries > THRESHOLD) {
           result = DoSomethingThatAlwaysWorks();
       }
   }

Ir toda ponteiros de função em uma rota estrutura. Só para combiná-lo, eu vou usar uma fila e alguns LINQ.

Queue<Action> actions = new Queue<Action>(new Action[] {
   obj.DoSomething,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingGuaranteed
});

actions.First(a => {
   try {
      a();
      return true;
   } catch (Exception) {
      return false;
   }
});

Como sobre (pseudocódigo):

try{ return doSomething(); }
catch(ExpectedException) { ...not much here probably...}

for(i = 0 to RETRIES){
try{ return doSomethingApproximately; }
catch(ExpectedException) { ...not much here probably...}
}

doSomethingGuaranteed();

Adenda:

Eu recomendo fortemente que você não usa valores de retorno especiais, porque isso significa que cada usuário da função tem de saber que alguns dos valores de retorno são especiais. Dependendo da gama da função, pode ser sensato para retornar uma parte comum da gama que pode ser tratada com, normalmente, por exemplo uma recolha vazio. Claro, isso pode tornar impossível de distinguir entre o fracasso, e a resposta "certa" de ser o conjunto vazio (neste exemplo).

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