Eu não como este fazer ... é esta traindo a língua?
-
10-07-2019 - |
Pergunta
Eu vi algo como o seguinte algumas vezes ... e eu odeio isso. É este, basicamente, 'traindo' a língua? Ou .. você consideraria isso seja 'ok' porque o IsNullOrEmpty é avaliada em primeiro lugar, o tempo todo?
(Poderíamos discutir se deve ou não uma corda deve ser NULL quando ele sai de uma função, mas isso não é realmente a questão.)
string someString;
someString = MagicFunction();
if (!string.IsNullOrEmpty(someString) && someString.Length > 3)
{
// normal string, do whatever
}
else
{
// On a NULL string, it drops to here, because first evaluation of IsNullOrEmpty fails
// However, the Length function, if used by itself, would throw an exception.
}
EDIT: Mais uma vez obrigado a todos por me lembrar dessa linguagem fundamental. Enquanto eu sabia "porque" ele funcionou, não posso acreditar que eu não sei / lembro o nome do conceito.
(Caso alguém queira qualquer fundo .. Eu vim em cima deste, enquanto solução de problemas exceções geradas por cordas NULL e .length> x exceções ... em diferentes lugares do código. Então, quando eu vi o código acima, além de tudo o resto, a minha frustração assumiu a partir daí.)
Solução
Você está tirando proveito de um recurso de linguagem conhecida como curtos-circuitos. Isso não é batota a língua, mas de fato usando um recurso exatamente como ele foi projetado para ser usado.
Outras dicas
Se você está perguntando se o seu ok para dependem do "curto-circuito" operadores relacionais &&
e ||
, então sim isso é totalmente bem.
Não há nada de errado com isso, como você só quer ter certeza de que você não vai obter uma exceção nullpointer.
Eu acho que é razoável a fazer.
Com as extensões que você pode torná-lo mais limpo, mas o conceito básico ainda seria válido.
Este código é totalmente válido, mas eu gosto de usar o Coalesça Operador nulo para verificações de tipo evitar nulo.
string someString = MagicFunction() ?? string.Empty;
if (someString.Length > 3)
{
// normal string, do whatever
}
else
{
// NULL strings will be converted to Length = 0 and will end up here.
}
Não há nada de errado com isso.
Se (condições são avaliadas da esquerda para a direita, por isso é perfeitamente possível empilhá-los assim.
Este é um código válido, na minha opinião (embora declarando uma variável e atribuindo-lhe na próxima linha é muito chato), mas provavelmente você deve perceber que você pode entrar no else-bloco também na condição em que o comprimento do string é <3.
Isso me parece um uso perfeitamente razoável de lógica de curto-circuitting - se alguma coisa, é batota com o idioma. Vim só recentemente de VB6 que não fez sempre curto-circuito, e que realmente ficar irritado me .
Um problema que atente para é que você pode precisar de teste para nulo novamente nessa cláusula else, uma vez que - como está escrito - você está enrolando até lá com as duas cordas nulos e comprimento inferior a-três cordas .
Isto é perfeitamente válido e não há nada de errado com a usá-lo dessa forma. Se você está seguindo o comportamento documentado para o idioma que está tudo bem. Em C # a sintaxe que você está usando são os operadores lógicos condicionais e thier bahviour docemented pode ser encontrado em MSDN
Para mim é a mesma de quando você não usa parênteses para quando fazer a multiplicação e adição na mesma instrução porque os documentos de linguagem que as operações de multiplicação vai ficar realizadas em primeiro lugar.
Baseando-se em curto-circuito é a "coisa certa" para fazer na maioria dos casos. Isso leva a terser código com menos peças móveis. O que geralmente significa mais fácil de manter. Isto é especialmente verdadeiro em C e C ++.
Gostaria de reconsiderar seriamente a contratação de alguém que não está familiarizado com (e não sabe como usar) operações de curto-circuitos.
acho que é OK :) Você só está certificando-se de que você não acessar uma variável NULL. Na verdade, eu sempre faço essa verificação antes de fazer qualquer operação na minha variável (também, ao indexar coleções e assim) - que é mais seguro, uma prática recomendada, isso é tudo ..
Faz sentido, porque C # por curto-circuitos padrão as condições, então eu acho que é bom para usar isso a seu favor. Em VB, pode haver alguns problemas se os usos desenvolvedor e em vez de AndAlso.
Eu não acho que é diferente do que algo como isto:
INT* pNumber = GetAddressOfNumber();
if ((pNUmber != NULL) && (*pNumber > 0))
{
// valid number, do whatever
}
else
{
// On a null pointer, it drops to here, because (pNumber != NULL) fails
// However, (*pNumber > 0), if used by itself, would throw and exception when dereferencing NULL
}
É apenas tirando proveito de um recurso na língua. Este tipo de linguagem tem sido de uso comum, eu acho, já que C começou a ser executado expressões booleanas dessa maneira (ou qualquer linguagem que fez isso primeiro).)
Se fosse código em C que você compilado em conjunto, não só é um curto-circuito o comportamento certo, é mais rápido . Na máquina de langauge as partes da instrução if são avaliados um após o outro. Não curto-circuito é mais lento.
código de escrita custar muito $ para uma empresa. Mas mantê-la custar mais!
Então, eu estou OK com o seu ponto: acaso é que esta linha de código não será compreendido imediatamente pelo cara que vai ter que lê-lo e corrigi-lo em 2 anos
.Claro, ele será solicitado a corrigir um bug produção crítica. Ele irá procurar aqui e ali e pode não perceber isso.
Devemos sempre código para o próximo cara e ele pode ser menos inteligente que nós somos. Para mim, esta é a única coisa a lembrar.
E isto implica que usamos recursos de linguagem evidentes e evitar os outros.
Todo o melhor, Sylvain.
Um pouco fora do tópico, mas se você rand o mesmo exemplo em vb.net como este
dim someString as string
someString = MagicFunction()
if not string.IsNullOrEmpty(someString) and someString.Length > 3 then
' normal string, do whatever
else
' do someting else
end if
este iria bater em um nula (nada) corda, mas em VB.Net você código-o como segue faço o mesmo em C #
dim someString as string
someString = MagicFunction()
if not string.IsNullOrEmpty(someString) andalso someString.Length > 3 then
' normal string, do whatever
else
' do someting else
end if
adicionando o andalso torná-lo comportar-se da mesma forma, também ele lê melhor. como alguém que faz tanto VB e c' desenvolvimento o segundo show de vb que o login é slighty diferente e por isso easyer explicar a alguém que não é um differeance etc.
Drux