Ocasionalmente, encontro métodos onde um desenvolvedor optou por retornar algo que não é crítico para a função. Quero dizer, ao olhar para o código, aparentemente funciona tão bem quanto um void
e depois de um momento de reflexão, pergunto "Por quê?" Isso soa familiar?
Às vezes, eu concordo que na maioria das vezes é melhor retornar algo como a bool
ou int
, em vez disso, basta fazer a void
. Não tenho certeza, no geral, sobre os prós e contras.
Dependendo da situação, retornar um int
pode informar o chamador da quantidade de linhas ou objetos afetados pelo método (por exemplo, 5 registros salvos no MSSQL). Se um método como "InsertSomething" retornar um valor booleano, posso ter o método projetado para retornar true
se for bem-sucedido false
. O chamador pode optar por agir ou não nessas informações.
Por outro lado,
- Isso pode levar a um objetivo menos claro de uma chamada de método? A má codificação geralmente me obriga a verificar novamente o conteúdo do método. Se retornar algo, informará que o método é do tipo que você precisa fazer com o resultado retornado.
- Outra questão seria, se a implementação do método é desconhecida para você, o que o desenvolvedor decidiu retornar que não é essencial para a função? Claro que você pode comentar.
- O valor de retorno deve ser processado, quando o processamento puder ser finalizado no colchete de fechamento do método.
- O que acontece sob o capô? O método chamado foi causado
false
por um erro gerado? Ou retornou falso devido ao resultado avaliado?
Quais são suas experiências com isso? Como você agiria sobre isso?
fonte
void
pelo menos permite que o desenvolvedor saiba que o valor de retorno do método é inconseqüente; faz uma ação, em vez de calcular um valor.Respostas:
No caso de um valor de retorno booleano para indicar o sucesso ou falha de um método, prefiro o
Try
paradigma -prefix usado em vários métodos .NET.Por exemplo, um
void InsertRow()
método pode lançar uma exceção se já existir uma linha com a mesma chave. A questão é: é razoável supor que o chamador garanta que sua linha seja exclusiva antes de chamar InsertRow? Se a resposta for não, também forneceria umbool TryInsertRow()
que retornará false se a linha já existir. Em outros casos, como erros de conectividade db, o TryInsertRow ainda pode gerar uma exceção, supondo que a manutenção da conectividade db seja de responsabilidade do chamador.fonte
O IMHO retornando um "código de status" decorre dos tempos históricos, antes que as exceções se tornassem comuns em idiomas de nível médio a superior, como o C #. Hoje em dia é melhor lançar uma exceção se algum erro inesperado impedir o êxito do seu método. Dessa forma, é certo que o erro não passa despercebido e o chamador pode lidar com isso conforme apropriado. Portanto, nesses casos, é perfeitamente bom que um método não retorne nada (ou seja
void
), em vez de um sinalizador de status booleano ou um código de status inteiro. (Obviamente, deve-se documentar quais exceções o método pode gerar e quando.)Por outro lado, se for uma função no sentido estrito, isto é, realiza algum cálculo com base nos parâmetros de entrada, e espera-se retornar o resultado desse cálculo, o tipo de retorno é óbvio.
Há uma área cinza entre os dois, quando se pode decidir retornar algumas informações "extras" do método, se isso for considerado útil para os chamadores. Como seu exemplo sobre o número de linhas afetadas em uma inserção. Ou, para um método para colocar um elemento em uma coleção associativa, pode ser útil retornar o valor anterior associado a essa chave, se houver algum. Esses usos podem ser identificados analisando cuidadosamente os cenários de uso (conhecidos e previstos) de uma API.
fonte
A resposta de Pedro cobre bem as exceções. Outra consideração aqui envolve a Separação de Consulta de Comando
O princípio do CQS diz que um método deve ser um comando ou uma consulta e não ambos. Os comandos nunca devem retornar um valor, modificar apenas o estado e as consultas devem retornar e não modificar o estado. Isso mantém a semântica muito clara e ajuda a tornar o código mais legível e sustentável.
Existem alguns casos em que violar o princípio CQS é uma boa ideia. Geralmente, isso envolve desempenho ou segurança de thread.
fonte
Seja qual for o caminho, você vai caminhar com isso. Não há valores de retorno para uso futuro (por exemplo, as funções sempre retornam verdadeiras), é um terrível desperdício de esforço e não torna o código mais claro de se ler. Quando você tem um valor de retorno, deve sempre usá-lo e, para poder usá-lo, deve ter pelo menos 2 valores de retorno possíveis.
fonte
Eu costumava escrever muitas funções nulas. Mas desde que eu iniciei todo o método de encadeamento de crack, comecei a retornar isso em vez de nulo - é melhor deixar alguém tirar proveito do retorno, porque você não pode agachar com nulo. E se eles não querem fazer nada com isso, eles podem simplesmente ignorá-lo.
fonte
Ruby
algum momento? Foi isso que me apresentou ao encadeamento de métodos.return Thing.Change1().Change2();
está esperando alterarThing
e retornar uma referência ao original ou se deve retornar uma referência a uma coisa nova que difere da original, deixando o original intocado.