É uma boa prática chamar um método que retorne valores verdadeiros ou falsos em uma instrução if?
Algo assim:
private void VerifyAccount()
{
if (!ValidateCredentials(txtUser.Text, txtPassword.Text))
{
MessageBox.Show("Invalid user name or password");
}
}
private bool ValidateCredentials(string userName, string password)
{
string existingPassword = GetUserPassword(userName);
if (existingPassword == null)
return false;
var hasher = new Hasher { SaltSize = 16 };
bool passwordsMatch = hasher.CompareStringToHash(password, existingPassword);
return passwordsMatch;
}
ou é melhor armazená-los em uma variável e compará-los usando se mais valores como este
bool validate = ValidateCredentials(txtUser.Text, txtPassword.Text);
if(validate == false){
//Do something
}
Não estou me referindo apenas ao .NET, estou me referindo à pergunta em todas as linguagens de programação. Acontece que usei o .NET como exemplo
if (!validate)
vez deif (validate == false)
.IsValidCredentials
, embora gramaticalmente estranho, é um formato comum para indicar um valor de retorno booleano.!
é o operador "NOT", ele nega qualquer expressão booleana. Entãoif (!validate)
é o oposto deif (validate)
. A instrução if será inserida sevalidate
não for verdadeira.Respostas:
Como com todas essas coisas, depende.
Se você não usar o resultado da sua chamada para
ValidateCredentials
, não será necessário (exceto para fins de depuração) armazenar o resultado em uma variável local. No entanto, se tornar o código mais legível (e, portanto, mais sustentável), uma variável será aceita.O código não será mensurável menos eficiente.
fonte
!ValidateCredentials
é mais legível porque diz explicitamente o que está fazendo no código. Está muito claro. Se a função que você está chamando não tiver um nome de "auto-documentação", talvez seja melhor usar a variável Tal como está, eu recomendo omitir a variável e ficar com o código de auto-documentação que você possui.Por que usar uma variável adicional? Prefiro usar a primeira abordagem, é mais legível e simples.
fonte
Sim, se o condicional não for simples o suficiente para incorporar e permitir que seja legível.
Você só deve fazer isso se estiver usando o valor em vários locais ou precisar dele para tornar o código mais legível. Caso contrário, a atribuição a uma variável é desnecessária. Código desnecessário é, na melhor das hipóteses, um desperdício e, na pior das hipóteses, uma fonte de um defeito.
fonte
Vamos ver...
Por se tratar de KISS , não há necessidade de criar uma variável adicional quando você pode ficar sem ela. Além disso, não há necessidade de digitar mais ... quando não há necessidade.
Mas, como você SECA , se você estava ligando mais tarde
ValidateCredentials
e se viu digitando,ValidateCredentials(txtUser.Text, txtPassword.Text)
sabe que deveria ter criado uma variável adicional.fonte
Sim, geralmente é bom usar métodos como se fossem condições. É útil, porém, se o nome do método indicar que o método retorna um bool; por exemplo, CanValidateCredentials. Nas linguagens de estilo C, esse método geralmente assume a forma de prefixos Is e Can e, em Ruby, com o '?' sufixo.
fonte
if (cat.canOpenCanOfCatFood())
.Há outra preocupação que ainda não foi apontada: avaliação de curto-circuito . Qual é a diferença entre esses dois fragmentos de código?
Ex # 1:
Ex # 2:
Esses dois fragmentos de código parecem fazer a mesma coisa, mas se seu idioma suportar a avaliação de curto-circuito, esses dois fragmentos serão diferentes. A avaliação de curto-circuito significa que o código avaliará o mínimo necessário para passar ou falhar em uma condição. Se o exemplo 1, se foo () retornar false, bar () e baz () nem serão avaliados. Isso é útil se baz () for uma chamada de função de longa duração, porque você poderá ignorá-la se foo () retornar false ou foo () retornar true e bar () retornar false.
Este não é o caso no exemplo # 2. foo (), bar () e baz () são sempre avaliados. Se você espera que bar () e baz () exibam efeitos colaterais, você terá problemas com o Exemplo 1. O exemplo 1 acima é realmente equivalente a isso:
Ex # 3:
Esteja ciente dessas diferenças no seu código ao escolher entre os exemplos 1 e 2.
fonte
Expandindo um pouco a questão da legibilidade ...
Posso pensar em duas boas razões para armazenar o resultado em uma variável:
Se você estiver usando a condição mais de uma vez, salvá-la em uma variável significa que você só precisa chamar a função uma vez. (Isso pressupõe que o valor armazenado ainda é válido; se você precisar testá-lo novamente, é claro que isso não se aplica.)
Se o armazenamento em uma variável melhorar a legibilidade, forneça à condição um nome mais significativo do que o que você vê na chamada de função.
Por exemplo, isto:
não ajuda a legibilidade, mas isso:
provavelmente sim, já que não é imediatamente óbvio que
feof(file1) && feof(file2)
significa que terminamos o processamento.A
passwordsMatch
variável na pergunta é provavelmente um exemplo melhor que o meu.As variáveis de uso único são úteis se atribuírem um nome significativo a algum valor. (Isso é claro para o benefício do leitor humano.)
fonte
done_processing
variável. Afinal, o nomedone_processing
tem a função de um comentário. E um comentário real me permite dizer uma ou duas palavras sobre por que essa condição sinaliza que terminamos o processamento. Não é que eu sou um grande comentarista, porém, eu provavelmente faria nem em código real ...done_processing
é uma maneira mais durável de expressar a intenção.