Qual destes é melhor para manutenção?
if (byteArrayVariable != null)
if (byteArrayVariable .Length != 0)
//Do something with byteArrayVariable
OU
if ((byteArrayVariable != null) && (byteArrayVariable.Length != 0))
//Do something with byteArrayVariable
Prefiro ler e escrever o segundo, mas lembro-me de ler em código completo que fazer coisas assim é ruim para a manutenção.
Isso ocorre porque você está confiando no idioma para não avaliar a segunda parte do if
se a primeira parte for falsa e nem todos os idiomas fazem isso. (A segunda parte lançará uma exceção se avaliada com um nulo byteArrayVariable
.)
Não sei se isso é realmente algo para se preocupar ou não, e gostaria de obter um feedback geral sobre a questão.
Obrigado.
&&
e na||
avaliação de curto-circuito. Indo de um idioma para outro geralmente tem algumas desvantagens, e é bom ser firme ao fazer revisões de código para ajudar a capturar esses pequenos problemas.Respostas:
Eu acho que a segunda forma é boa e também representa mais claramente o que você está tentando fazer. Você diz que...
Não importa se todos os idiomas fazem isso. Você está escrevendo em um idioma específico, então só importa se esse idioma fizer isso. Caso contrário, você está basicamente dizendo que não deve usar os recursos de um idioma específico, porque outros idiomas podem não suportar esses recursos, e isso é bobagem.
fonte
Estou surpreso que ninguém tenha mencionado isso (por isso espero não estar interpretando mal a pergunta) - mas ambos são péssimos!
A melhor alternativa seria usar as saídas antecipadas (colocando uma declaração de retorno no início do código, se nenhum outro código for executado). Isso pressupõe que seu código seja relativamente bem refatorado e que cada método tenha um objetivo conciso.
Nesse ponto, você faria algo como:
Pode parecer muito com validação - e é exatamente isso que é. Ele valida que as condições foram satisfeitas para o método - as duas opções que você ofereceu ocultaram a lógica real nas verificações de pré-condição.
Se o seu código é muito espaguete (métodos loooong, muitos ifs aninhados com lógica dispersa entre eles etc.), você deve se concentrar no problema maior de colocar seu código em forma antes dos problemas estilísticos menores. Dependendo do seu ambiente e da gravidade da bagunça, existem algumas ótimas ferramentas para ajudar (por exemplo, o Visual Studio possui uma função de refatoração "Extrair método").
Como Jim menciona, ainda há espaço para debate sobre como estruturar a saída antecipada. A alternativa ao que está acima seria:
fonte
Não perca tempo tentando capturar todas essas condições. Se você pode desqualificar os dados ou condições, faça-o assim que possível.
Isso permite que você adapte seu código muito mais facilmente para novas condições
fonte
Seu exemplo é o exemplo perfeito de por que os aninhados
ifs
são uma abordagem ruim para a maioria dos idiomas que oferecem suporte adequado à comparação booleana. Aninharifs
cria uma situação em que sua intenção não é clara. É necessário que o segundoif
siga imediatamente o primeiro? Ou é apenas porque você ainda não colocou outra operação lá?Nesse caso, esses praticamente devem estar juntos. Eles estão agindo como um guarda para garantir que você não execute uma operação que resultaria em uma exceção. Usando aninhado
ifs
, você deixa para a interpretação da pessoa que o segue se os dois representam uma guarda de duas partes ou alguma outra lógica de ramificação. Ao combiná-los em um únicoif
, estou afirmando isso. É muito mais difícil esgueirar-se para dentro de uma operação onde não deveria estar.Eu sempre vou favorecer a comunicação clara da minha intenção sobre a afirmação estúpida de alguém de que "não funciona em todas as línguas". Adivinha o que ...
throw
também não funciona em todas as linguagens, isso significa que eu não devo usá-lo ao codificar em C # ou Java e, em vez disso, devo confiar nos valores de retorno para sinalizar quando houve um problema?Tudo isso dito, é muito mais legível invertê-lo e retornar ao método se um deles não estiver satisfeito, como diz o STW em sua resposta.
fonte
Nesse caso, suas duas cláusulas estão diretamente relacionadas, portanto, a segunda forma é preferível.
Se eles não fossem relacionados (por exemplo, uma série de cláusulas de guarda em condições diferentes), eu preferiria a 1ª forma (ou refataria um método com um nome que represente o que a condição composta realmente representa).
fonte
Se você trabalha em Delphi, a primeira maneira é, em geral, mais segura. (Para o exemplo dado, não há muito a ganhar com o uso de ifs aninhados.)
O Delphi permite que você especifique se as expressões booleanas devem ou não ser avaliadas ou "curto-circuitadas" através de opções do compilador. A maneira # 1 (ifs aninhados) permite garantir que a segunda cláusula execute se e somente se (e estritamente depois ) a primeira cláusula for avaliada como verdadeira.
fonte
O segundo estilo pode sair pela culatra no VBA, pois se o primeiro teste for se o objeto for gerado, ele ainda fará o segundo teste e obterá um erro. Acabei de adquirir o hábito no VBA ao lidar com a verificação de objetos para sempre usar o primeiro método.
fonte
O segundo formulário é mais legível, especialmente se você estiver usando blocos {} em torno de cada cláusula, porque o primeiro formulário levará a {} blocos aninhados e a vários níveis de indentação, o que pode ser difícil de ler (você precisa contar espaços de indentação) para descobrir onde cada bloco termina).
fonte
Acho que ambos são legíveis e não aceito o argumento de que você deve se preocupar com a manutenção do código se quiser trocar de idioma.
Em alguns idiomas, a segunda opção tem um desempenho melhor, portanto seria a escolha mais clara.
fonte
Estou contigo; Eu faço da segunda maneira. Para mim, é logicamente mais claro. A preocupação de que algumas linguagens executem a segunda parte, mesmo que a primeira seja avaliada como falsa, parece um pouco tola para mim, pois nunca na minha vida escrevi um programa executado em "algumas linguagens"; meu código sempre parece existir em um idioma específico, que pode lidar com essa construção ou não. (E se eu não tiver certeza se o idioma específico pode lidar com isso, é algo que realmente preciso aprender, não é?)
Na minha opinião, o perigo da primeira maneira de fazer isso é que me deixa vulnerável a inserir acidentalmente código fora desse
if
bloco aninhado quando não pretendia. O que, reconhecidamente, dificilmente é uma grande preocupação, mas parece mais razoável do que se preocupar se meu código é independente de idioma.fonte
Eu prefiro a segunda opção, porque é mais legível.
Se a lógica que você está implementando for mais complexa (verificar se uma sequência não é nula e não está vazia é apenas um exemplo), você pode fazer uma refatoração útil: extrair uma função booleana. Estou com @mipadi na observação "Code Complete" ("não importa se todos os idiomas fazem isso ...") Se o leitor do seu código não estiver interessado em procurar dentro da função extraída, a ordem em que operandos booleanos são avaliados torna-se uma questão discutível para eles.
fonte
mas essa é basicamente a segunda opção.
fonte