Eu tive uma discussão com um colega de trabalho sobre a quebra de uma return
declaração e a declaração que calcula o valor de retorno em duas linhas.
Por exemplo
private string GetFormattedValue()
{
var formattedString = format != null ? string.Format(format, value) : value.ToString();
return formattedString;
}
ao invés de
private string GetFormattedValue()
{
return format != null ? string.Format(format, value) : value.ToString();
}
Em termos de código, não vejo realmente um valor na primeira variante. Para mim, o último é mais claro, principalmente para métodos tão curtos. Seu argumento foi que a variante anterior é mais fácil de depurar - o que é um mérito muito pequeno, já que o VisualStudio nos permite uma inspeção muito detalhada das instruções, quando a execução é interrompida devido a um ponto de interrupção.
Minha pergunta é, se ainda é um ponto válido escrever código menos claro, apenas para facilitar a depuração de um vislumbre? Existem outros argumentos para a variante com o cálculo e a return
instrução de divisão ?
fonte
private string GetFormattedValue() => string.Format(format ?? "{0}", value);
Respostas:
A introdução de variáveis explicativas é uma refatoração bem conhecida que às vezes pode ajudar a tornar expressões complicadas melhor legíveis. No entanto, no caso mostrado,
Além disso, versões mais recentes do depurador do Visual Studio podem mostrar o valor de retorno de uma função na maioria dos casos, sem introduzir uma variável supérflua (mas cuidado, existem algumas ressalvas, dê uma olhada nesta postagem mais antiga do SO e nas respostas diferentes ).
Portanto, neste caso específico, eu concordo com você, no entanto, há outros casos em que uma variável explicativa pode realmente melhorar a qualidade do código.
fonte
result
como o nome da variável. Não é muito mais longo e mais fácil de depurarresult
frequentemente adiciona ruído ao código e raramente aumenta a legibilidade, que é exatamente o ponto da minha resposta. Isso pode ser justificado no contexto em que ajuda na depuração, mas eu evitaria ao usar um depurador que não precisa de uma variável separada.result
transmite as informações de que esse é o valor resultante da função, para que você possa vê-lo antes que a função retorne.Dados os fatos que:
a) Não há impacto no código final, pois o compilador otimiza a variável.
b) Separá-lo melhora a capacidade de depuração.
Pessoalmente, cheguei à conclusão de que é uma boa prática separá-los 99% do tempo.
Não há desvantagens materiais em fazê-lo dessa maneira. O argumento de que ele incha o código é um nome impróprio, porque o código inchado é um problema trivial em comparação com o código ilegível ou difícil de depurar. Além disso, esse método não pode, por si só, criar código confuso, isso depende inteiramente do desenvolvedor.
fonte
Freqüentemente, a introdução de uma variável apenas para nomear algum resultado é muito útil quando torna o código mais auto-documentado. Nesse caso, isso não é um fator, porque o nome da variável é muito semelhante ao nome do método.
Observe que os métodos de uma linha não têm nenhum valor inerente. Se uma alteração introduz mais linhas, mas torna o código mais claro, é uma boa alteração.
Mas, em geral, essas decisões são altamente dependentes de suas preferências pessoais. Por exemplo, acho as duas soluções confusas porque o operador condicional está sendo usado desnecessariamente. Eu teria preferido uma declaração se. Mas em sua equipe você pode ter concordado em diferentes convenções. Então faça o que suas convenções sugerem. Se as convenções forem silenciosas em um caso como esse, observe que essa é uma mudança extremamente pequena que não importa a longo prazo. Se esse padrão ocorrer repetidamente, talvez inicie uma discussão sobre como você, como equipe, deseja lidar com esses casos. Mas isso é dividir os cabelos entre "bom código" e "talvez um pouco melhor".
fonte
?
e a:
eu usoif() {
e} else {
- - - -\\ :)
Em resposta às suas perguntas:
Minha pergunta é: se ainda é um ponto válido escrever código menos claro, apenas para facilitar a depuração de um vislumbre?
Sim. De fato, parte da sua declaração anterior parece-me um pouco míope (veja em negrito abaixo) " O argumento dele foi que a variante anterior é mais fácil de depurar - o que é um mérito muito pequeno , já que o VisualStudio permite uma inspeção muito detalhada das instruções, quando a execução é interrompida devido a um ponto de interrupção " .
Facilitar a depuração (quase) nunca é de " pequeno mérito " porque, segundo algumas estimativas, 50% do tempo de um programador é gasto na depuração ( Software de Depuração Reversível ).
Existem outros argumentos para a variante com o cálculo de divisão e a declaração de retorno?
Sim. Alguns desenvolvedores argumentam que o cálculo dividido é mais fácil de ler. Isso, é claro, ajuda na depuração, mas também ajuda quando alguém está tentando decifrar quaisquer regras de negócios que seu código possa executar ou aplicar.
NOTA: As regras de negócios podem ser melhor atendidas em um banco de dados, pois podem ser alteradas com frequência. No entanto, a codificação clara nessa área ainda é fundamental. ( Como criar um mecanismo de regras de negócios )
fonte
Eu iria além:
Por quê?
Usar operadores ternários para uma lógica mais complexa seria ilegível; portanto, você usaria um estilo como o acima para instruções mais complexas. Sempre usando esse estilo, seu código é consistente e mais fácil para um ser humano analisar. Além disso, introduzindo esse tipo de consistência (e usando lints de código e outros testes), você pode evitar
goto fail
erros de tipo.Outra vantagem é que seu relatório de cobertura de código informará se você esqueceu de incluir um teste para
format
não ser nulo. Este não seria o caso para o operador ternário.Minha alternativa preferida - se você estiver no grupo "obtenha um retorno o mais rápido possível" e não contra vários retornos de um método:
Portanto, você pode ver o último retorno para ver qual é o padrão.
É importante ser consistente - e fazer com que todos os seus métodos sigam uma ou outra convenção.
fonte
value.ToString()
é chamado desnecessariamente quando o formato é não nulo. No caso geral, isso pode incluir cálculos não triviais e pode levar mais tempo que a versão, incluindo uma sequência de formato. Considere, por exemplo, umvalue
que armazena o PI com um milhão de casas decimais e uma sequência de formato que solicita apenas os primeiros dígitos.private string GetFormattedValue() => string.Format(format ?? "{0}", value);
mesmo afeta e use testes de unidade para garantir a correção em vez de confiar no depurador.Eu não acho que essa técnica possa ser justificada pela necessidade de depurar. Eu já encontrei essa abordagem mil vezes e, de tempos em tempos, continuo fazendo isso, mas sempre lembro o que Martin Fowler disse sobre a depuração :
fonte
Eu acho que algumas pessoas estão se pendurando em questões tangenciais à questão, como o operador ternário. Sim, muitas pessoas odeiam isso, então talvez seja bom falar sobre isso de qualquer maneira.
Com relação ao foco da sua pergunta, movendo a declaração retornada para ser referenciada por uma variável ...
Esta pergunta faz duas suposições que eu não concordo:
Que a segunda variante é mais clara ou fácil de ler (digo que o oposto é verdadeiro) e
que todo mundo usa o Visual Studio. Eu usei o Visual Studio várias vezes e posso usá-lo muito bem, mas geralmente estou usando outra coisa. Um ambiente de desenvolvimento que força um IDE específico é do qual eu seria cético.
Dividir algo com uma variável nomeada raramente dificulta a leitura, mas quase sempre faz o oposto. A maneira específica pela qual alguém faz isso pode causar problemas, como se um supervisor de auto-documentação o fizesse
var thisVariableIsTheFormattedResultAndWillBeTheReturnValue = ...
obviamente ruim, mas esse é um problema separado.var formattedText = ...
está bem.Neste específico caso , e possivelmente em muitos casos, já que estamos falando de 1-liners, a variável não diria muito a você que o nome da função ainda não o informou. Portanto, a variável não adiciona tanto. O argumento de depuração ainda pode se manter, mas, novamente, neste caso específico, não vejo nada que possa ser o seu foco durante a depuração e sempre pode ser facilmente alterado posteriormente se, de alguma forma, alguém precisar desse formato para depuração ou qualquer outra coisa.
Em geral, e você solicitou a regra geral (seu exemplo foi apenas isso, um exemplo de forma generalizada), todos os argumentos feitos a favor da variante 1 (2-liner) estão corretos. Essas são boas diretrizes para ter. Mas as diretrizes precisam ser flexíveis. Por exemplo, o projeto no qual estou trabalhando agora tem no máximo 80 caracteres por linha, então divido muitas linhas, mas geralmente encontro as linhas 81 a 85 caracteres que seriam difíceis de dividir ou reduzir a legibilidade e deixo-as o limite.
Como é improvável agregar valor, eu não faria duas linhas para o exemplo específico dado. Eu faria a variante 2 (o liner 1) porque os pontos não são fortes o suficiente para fazer o contrário neste caso.
fonte