Não é razoável esperar que Any () * not * lance uma exceção de referência nula?

41

Quando você cria um método de extensão, é claro, pode chamá-lo null. Mas, diferentemente de uma chamada de método de instância, chamá-lo como null não precisa gerar um NullReferenceException-> você deve verificar e ativá-lo manualmente.

Para a implementação do método de extensão Linq, a Any()Microsoft decidiu que eles deveriam lançar um ArgumentNullException( https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/AnyAll.cs ).

Me irrita ter que escrever if( myCollection != null && myCollection.Any() )

Como cliente deste código, estou errado em esperar que, por exemplo ((int[])null).Any(), retorne false?

esta extensão
fonte
41
no C # 6, você pode simplificar sua verificação para if (myCollection? .Any () == true)
17 de 26
5
Mesmo no F #, que realmente não usa nulos, exceto pela interoperabilidade com outras linguagens .NET, null |> Seq.isEmptylança System.ArgumentNullException: Value cannot be null. A expectativa parece ser que você não passará valores indefinidos para algo que se espera que exista, portanto, ainda é uma exceção quando você tem um nulo. Se é uma questão de inicialização, eu começaria com uma sequência vazia em vez de a null.
Aaron M. Eshbach
21
É por isso que você não deve retornar nullao lidar com coleções, mas usar uma coleção vazia nesses casos.
Bakuriu 18/09/18
31
Bem, por que é nulo em primeiro lugar? Você não quer que o nulo seja contado como vazio, porque não está vazio, é algo completamente diferente. Talvez você queira que seja contado como vazio no seu caso, mas adicionar esse tipo de coisa ao idioma leva a erros.
user253751
22
Devo salientar que todo método LINQ lança um argumento nulo. Anyé apenas consistente.
Sebastian Redl

Respostas:

157

Eu tenho uma sacola com cinco batatas. Existem .Any()batatas na sacola?

" Sim " , você diz.<= true

Pego todas as batatas e as como. Existem .Any()batatas na sacola?

" Não " , você diz.<= false

Eu incinero completamente a bolsa no fogo. Existem .Any()batatas na bolsa agora?

" Não há bolsa ."<= ArgumentNullException

Dan Wilson
fonte
3
Mas, vagamente, não há batatas na sacola? Falso implica Falso ... (Não discordo, apenas uma segunda perspectiva).
D. Ben Knoble
6
mais praticamente, alguém lhe entrega uma caixa fechada de uma fonte desconhecida. O saco na caixa contém batatas? Estou interessado apenas em 2 cenários - A) há uma sacola na caixa que contém batatas ou B) não há batatas e / ou sacola na caixa. Semanticamente, sim, há uma diferença entre nulo e vazio, mas 99% das vezes não me importo.
Dave thieben
6
Você comeu cinco batatas cruas ?? Procure atendimento médico imediatamente.
21418 Oly
3
@Oly Dan os cozinhou no fogo, antes de comer e usar esse fogo para incinerar a sacola.
Ismael Miguel
3
@ D.BenKnoble: Sem ter visto o porta-malas do meu carro, você está disposto a testemunhar que não há corpos no porta-malas do meu carro? Não? Qual é a diferença entre verificar o tronco e não encontrar nada, ou não verificar o tronco? Você não pode simplesmente testemunhar agora, já que teria visto exatamente a mesma quantidade de corpos em ambos os casos? ... Essa é a diferença. Você não pode garantir algo se não conseguir confirmar em primeiro lugar. Você supõe que os dois são iguais, mas isso não é um dado. Em alguns casos, pode haver uma diferença importante entre os dois.
Flater
52

Primeiro, parece que esse código-fonte será lançado ArgumentNullException, não NullReferenceException.

Dito isto, em muitos casos, você já sabe que sua coleção não é nula, porque esse código é chamado apenas a partir de um código que sabe que a coleção já existe, portanto você não precisará inserir a verificação nula com muita frequência. Mas se você não sabe que ele existe, faz sentido verificar antes de chamá Any()-lo.

Como cliente deste código, estou errado em esperar que, por exemplo ((int[])null).Any(), retorne false?

Sim. A pergunta que Any()responde é "esta coleção contém algum elemento?" Se essa coleção não existir, a própria pergunta não fará sentido; não pode conter nem não conter nada, porque não existe.

Mason Wheeler
fonte
18
@ ChrisWohlert: Sua intuição me intriga. Você também acha que, semanticamente, uma pessoa inexistente é uma pessoa vazia, cujo nome é a sequência vazia e a idade é zero e assim por diante? E você acha que um conjunto contendo nullé equivalente a um conjunto contendo o conjunto vazio (e vice-versa)?
Ruakh 18/09/18
17
@ ChrisWohlert: Obviamente, um conjunto pode conter o conjunto vazio; mas você parece acreditar nisso { null }e { {} }deve ser equivalente. Eu acho isso fascinante; Não consigo me relacionar com isso.
ruakh 18/09/18
9
Em .Adduma nullcoleção, de alguma forma, também devemos criar uma coleção para nós?
Mateus
13
@ChrisWohlert "A é um conjunto vazio. B é um conjunto que contém uma melancia. A está vazio? Sim. B está vazio? Não. C está vazio? Uhhh ..."
user253751 18/18
16
Ponto pedante: não é o caso que, na teoria dos conjuntos, um conjunto inexistente seja um conjunto vazio. O conjunto vazio existe e qualquer conjunto inexistente não é (e, de fato, não é nada, pois não existe).
James_pic
22

Nulo significa falta de informação, não há elementos.

Você pode evitar um nulo mais amplo - por exemplo, use um dos enumeráveis ​​vazios internos para representar uma coleção sem elementos em vez de nulo.

Se você retornar nulo em algumas circunstâncias, poderá alterar isso para retornar a coleção vazia. (Caso contrário, se você encontrar nulos retornados pelos métodos da biblioteca (não o seu), isso é lamentável, e eu os agruparia para normalizar.)

Consulte também https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty

Erik Eidt
fonte
1
Isso nullnão significa que nenhum elemento é uma questão de usar uma convenção sensata. Basta pensar sobre OLESTRINGS nativas, onde ele realmente faz dizer isso.
Deduplicator
1
@Duplicador, você está falando sobre a vinculação e incorporação de objetos da Microsoft? Se você é, lembre-se de que o OLE é dos anos 90! Atualmente, muitas linguagens modernas (C #, Java, Swift) estão fornecendo recursos para eliminar / erradicar o uso de null.
Erik Eidt
2
@ErikEidt Eles estão fazendo isso, em parte, porque nullnão significa "falta de informação". nullnão tem uma única interpretação significativa. Em vez disso, é uma questão de como você o trata. nullàs vezes é usado para "informações ausentes", mas também para "nenhum elemento" e também para "um erro" ou "informações não inicializadas" ou "informações conflitantes" ou algo arbitrário e ad-hoc.
Derek Elkins
-1. Esta é uma decisão tomada pelo desenvolvedor, não por teorias abstratas. nullé absolutamente usado com frequência para significar "sem dados". Às vezes faz sentido. Outras vezes, não.
jpmc26 18/01
13

Além da sintaxe condicional nula , há outra técnica para aliviar esse problema: não deixe sua variável permanecer null.

Considere uma função que aceita uma coleção como parâmetro. Se, para os fins da função, nulle vazio forem equivalentes, você poderá garantir que ela nunca contenha nullno início:

public MyResult DoSomething(int a, IEnumerable<string> words)
{
    words = words ?? Enumerable.Empty<string>();

    if (!words.Any())
    {
        ...

Você pode fazer o mesmo ao buscar coleções de outro método:

var words = GetWords() ?? Enumerable.Empty<string>();

(Observe que nos casos em que você tem controle sobre uma função como GetWordse nullé equivalente à coleção vazia, é preferível retornar a coleção vazia em primeiro lugar.)

Agora você pode realizar qualquer operação que desejar na coleção. Isso é especialmente útil se você precisar executar muitas operações que falhariam quando a coleção nullocorrer e, nos casos em que você obtiver o mesmo resultado fazendo um loop ou consultando um enumerável vazio, permitirá eliminar ifcompletamente as condições.

jpmc26
fonte
12

Como cliente deste código, estou errado ao esperar que, por exemplo, ((int []) null) .Any () retorne false?

Sim, simplesmente porque você está em C # e esse comportamento é bem definido e documentado.

Se você estava criando sua própria biblioteca ou se estava usando um idioma diferente com diferentes culturas de exceção, seria mais razoável esperar falso.

Pessoalmente, sinto que o retorno falso é uma abordagem mais segura que torna seu programa mais robusto, mas é pelo menos discutível.

Telastyn
fonte
15
Essa 'robustez' costuma ser uma ilusão - se o código que gera a matriz repentinamente começar a gerar NULLs inesperadamente devido a um bug ou outro problema, seu código 'robusto' ocultará o problema. Às vezes, é um comportamento apropriado, mas não é um padrão seguro.
GoatInTheMachine 19/09/2018
1
@GoatInTheMachine - Não concordo que seja um padrão seguro, mas você está certo que esconde o problema e que esse comportamento é indesejável às vezes. Na minha experiência, ocultar o problema (ou confiar em testes de unidade para capturar os problemas de outros códigos) é melhor do que travar seu aplicativo, lançando exceções inesperadas. Quero dizer realmente - se o código de chamada estiver quebrado o suficiente para enviar nulos, qual é a chance de eles lidarem com exceções corretamente?
Telastyn
10
Se algo está quebrado, seja meu código, de outro colega ou de um cliente, prefiro que o código falhe imediatamente e as pessoas saibam sobre ele do que continuando em um estado potencialmente inconsistente por um período indeterminado de tempo. Ser capaz de fazer isso às vezes é um luxo e nem sempre é apropriado, mas é a abordagem que prefiro.
GoatInTheMachine 19/18
1
@GoatInTheMachine - Concordo com muitas coisas, mas as coleções tendem a ser diferentes. Tratar nulo como uma coleção vazia não é um comportamento extremamente inconsistente ou surpreendente.
Telastyn 19/09/19
8
Imagine que você tenha uma matriz preenchida a partir de um documento JSON recebido por meio de uma solicitação da Web e, em produção, um dos clientes da sua API repentinamente tenha um problema em que eles enviam através de JSON parcialmente inválido, fazendo com que você desserialize uma matriz como NULL, você prefere: o código, na pior das hipóteses, lançou uma exceção de referência NULL no momento em que a primeira solicitação incorreta foi recebida, que você veria no log e, em seguida, imediatamente dizia ao cliente para corrigir suas solicitações quebradas, OU seu código diz "oh, a matriz está vazia, nada façam!" e silenciosamente escreveu 'cesta de compras não tinha itens' para o banco de dados por algumas semanas?
GoatInTheMachine 20/09/2018
10

Se as verificações nulas repetidas o incomodarem, você poderá criar seu próprio método de extensão 'IsNullOrEmpty ()', para espelhar o método String com esse nome e agrupar a verificação nula e a chamada .Any () em uma única chamada.

Caso contrário, a solução, mencionada por 17 de 26 em um comentário da sua pergunta, também é mais curta que o método 'padrão' e razoavelmente clara para qualquer pessoa familiarizada com a nova sintaxe nulo-condicional.

if(myCollection?.Any() == true)
Theo Brinkman
fonte
4
Você também pode usar em ?? falsevez de == true. Isso me pareceria mais explícito (mais limpo), pois lida apenas com o caso de null, e não é realmente mais detalhado. Além disso, ==verificações de booleanos geralmente acionam meu reflexo de vômito. =)
jpmc26
2
@ jpmc26: Eu não sei muito sobre c #. Por que não é myCollection?.Any()suficiente?
Eric Duminil
6
@EricDuminil Devido à maneira como o operador condicional nulo funciona, myCollection?.Any()efetivamente retorna um booleano anulável em vez de um booleano comum (ou seja, booleano? Em vez de booleano). Não há conversão implícita do bool? para bool, e é um bool que precisamos neste exemplo em particular (para testar como parte da ifcondição). Portanto, devemos comparar explicitamente trueou fazer uso do operador de coalescência nula (??).
Steven Rands
@ jpmc26 ?? false é mais difícil de ler do que myCollection? .Any () == true. Independentemente do seu reflexo de vômito, == true é o que você está tentando testar implicitamente. ?? false apenas adiciona ruído adicional e você ainda precisa fazer uma avaliação em sua mente sobre o que acontece se nulo, que null == true falharia, quase sem que o leitor tenha que estar ciente disso ?..
Ryan The Leach
2
@RyanTheLeach Eu tenho que pensar muito mais sobre se ==realmente vai funcionar. Eu já sei o que acontece com um booleano intuitivamente quando só pode ser trueou false; Nem preciso pensar nisso. Mas jogue nullna mistura, e agora eu tenho que descobrir se isso ==é certo. ??em vez disso, apenas elimina o nullcaso, reduzindo-o novamente para truee false, que você já entende imediatamente. Quanto ao meu reflexo de vômito, quando o vejo pela primeira vez, meu instinto imediato é apenas excluí-lo, pois geralmente é inútil, o que você não quer que aconteça.
Jpmc26 21/09/19
8

Como cliente deste código, estou errado ao esperar que, por exemplo, ((int []) null) .Any () retorne false?

Se você se pergunta sobre expectativas, precisa pensar em intenções.

null significa algo muito diferente de Enumerable.Empty<T>

Como mencionado na resposta de Erik Eidt , há uma diferença de significado entre nulle uma coleção vazia.

Vamos primeiro dar uma olhada em como eles devem ser usados.

O livro Framework Design Guidelines: Convenções, expressões idiomáticas e padrões para bibliotecas .NET reutilizáveis, 2ª edição, escritas pelos arquitetos da Microsoft Krzysztof Cwalina e Brad Abrams, afirma as seguintes práticas recomendadas:

X NÃO retorne valores nulos das propriedades da coleção ou dos métodos que retornam coleções. Retorne uma coleção vazia ou uma matriz vazia.

Considere chamar um método que está obtendo dados de um banco de dados: se você receber uma matriz vazia ou Enumerable.Empty<T>isso simplesmente significa que seu espaço de amostra está vazio, ou seja, seu resultado é um conjunto vazio . Receber nullneste contexto, no entanto, significaria um estado de erro .

Na mesma linha de pensamento da analogia da batata de Dan Wilson , faz sentido fazer perguntas sobre seus dados, mesmo que sejam um conjunto vazio . Mas faz muito menos sentido, se não houver um conjunto .

Søren D. Ptæus
fonte
1
Se eles têm significados diferentes é altamente dependente do contexto. Freqüentemente, para o propósito de qualquer lógica que esteja à mão, eles representam conceitos equivalentes. Nem sempre , mas frequentemente.
precisa saber é
1
@ jpmc26: Acho que o objetivo desta resposta é dizer que, codificando diretrizes para c #, elas têm um significado diferente. Você sempre pode codificar corretamente onde nulo e vazio são os mesmos, se desejar. E, em alguns casos, você também pode fazer a mesma coisa, seja nulo ou vazio, mas isso não significa que eles significam a mesma coisa.
Chris
@ Chris E estou dizendo que as diretrizes de codificação de pessoas que criaram a linguagem não podem ser usadas como um substituto para avaliar seu código no contexto de seus requisitos, nas bibliotecas que você está usando e nos outros desenvolvedores com quem você trabalha. A idéia de que eles nunca serão equivalentes no contexto é o idealismo de torcer no céu. Eles podem até não ser equivalentes para os dados disponíveis em geral, mas são equivalentes para gerar um resultado em alguma função específica que você está escrevendo; nesse caso, você precisa oferecer suporte a ambos, mas garantir que eles gerem o mesmo resultado.
Jpmc26 21/09/19
Posso estar confuso com o que você está dizendo, mas quando nulo e vazio são equivalentes para gerar um resultado, não vejo por que você não usaria apenas separado é nulo e está vazio, em vez de querer um método que faça as duas coisas ao mesmo tempo, mas não permitem distingui-los em outras situações ...
Chris
@ Chris Estou me referindo a ter contextos diferentes (que geralmente correspondem a escopos). Considere uma função, por exemplo. nulle vazio pode resultar no mesmo valor de retorno para a função, mas isso não significa que nulle vazio significa exatamente a mesma coisa no escopo da chamada.
Jpmc26 22/09
3

Existem muitas respostas que explicam o porquê nulle o vazio são diferentes e opiniões suficientes tentam explicar por que eles devem ser tratados de maneira diferente ou não. No entanto, você está perguntando:

Como cliente deste código, estou errado ao esperar que, por exemplo, ((int []) null) .Any () retorne false?

É uma expectativa perfeitamente razoável . Você está tão certo quanto alguém que defende o comportamento atual. Concordo com a filosofia de implementação atual, mas os fatores determinantes não se baseiam apenas em considerações fora do contexto.

Dado que Any()sem predicado é essencialmente Count() > 0, o que você espera desse snippet?

List<int> list = null;
if (list.Count > 0) {}

Ou um genérico:

List<int> list = null;
if (list.Foo()) {}

Suponho que você espera NullReferenceException.

  • Any()é um método de extensão, ele deve se integrar perfeitamente ao objeto estendido e, em seguida, lançar uma exceção é a coisa menos surpreendente.
  • Nem toda linguagem .NET suporta métodos de extensão.
  • Você sempre pode ligar Enumerable.Any(null)e definitivamente espera ArgumentNullException. É o mesmo método e deve ser consistente com - possivelmente - quase TUDO no Framework.
  • Acessar um nullobjeto é um erro de programação , a estrutura não deve impor nulo como valor mágico . Se você usá-lo dessa maneira, é sua responsabilidade lidar com isso.
  • É opinativo , você pensa de um jeito e eu acho de outro jeito. A estrutura deve ser o mais sem opinião possível.
  • Se você tem um caso especial, deve ser consistente : você precisa tomar decisões cada vez mais altamente opinativas sobre todos os outros métodos de extensão: se Count()parece uma decisão fácil, Where()não é. Que tal Max()? Ele lança uma exceção para uma lista VAZIA, não deveria lançar também para uma null?

O que os designers de bibliotecas fizeram antes do LINQ foi introduzir métodos explícitos quando nullé um valor válido (por exemplo String.IsNullOrEmpty()), então eles tinham que ser consistentes com a filosofia de design existente . Dito isto, mesmo se bastante trivial para escrever, dois métodos EmptyIfNull()e EmptyOrNull()pode ser útil.

Adriano Repetti
fonte
1

Jim deve deixar batatas em cada saco. Caso contrário, eu vou matá-lo.

Jim tem uma sacola com cinco batatas. Existem .Any()batatas na sacola?

"Sim", você diz. <= true

Ok, então Jim vive desta vez.

Jim pega todas as batatas e as come. Existem. Alguma () batata na sacola?

"Não", você diz. <= false

Hora de matar Jim.

Jim incinera completamente a bolsa no fogo. Existem. Alguma () batata na bolsa agora?

"Não há bolsa." <= ArgumentNullException

Jim deveria viver ou morrer? Bem, não esperávamos isso, então eu preciso de uma decisão. Deixar Jim se safar com isso é um bug ou não?

Você pode usar anotações para sinalizar que não está suportando nenhuma travessia nula dessa maneira.

public bool Any( [NotNull] List bag ) 

Mas sua cadeia de ferramentas precisa apoiá-la. O que significa que você provavelmente ainda acabará escrevendo cheques.

candied_orange
fonte
0

Se isso te incomoda muito, sugiro um método de extensão simples.

static public IEnumerable<T> NullToEmpty<T>(this IEnumerable<T> source)
{
    return (source == null) ? Enumerable.Empty<T>() : source;
}

Agora você pode fazer isso:

List<string> list = null;
var flag = list.NullToEmpty().Any( s => s == "Foo" );

... e o sinalizador será definido como false.

John Wu
fonte
2
Mais natural escrever a returndeclaração como:return source ?? Enumerable.Empty<T>();
Jeppe Stig Nielsen
Isso não responde à pergunta.
21918 Kenneth K.
@ KennethK.mas parece resolver o problema apresentado.
RQDQ 20/09/18
0

Esta é uma pergunta sobre os métodos de extensão do C # e sua filosofia de design. Portanto, acho que a melhor maneira de responder a essa pergunta é citar a documentação do MSDN com a finalidade dos métodos de extensão :

Os métodos de extensão permitem "adicionar" métodos a tipos existentes sem criar um novo tipo derivado, recompilar ou modificar o tipo original. Os métodos de extensão são um tipo especial de método estático, mas são chamados como se fossem métodos de instância no tipo estendido. Para o código do cliente escrito em C #, F # e Visual Basic, não há diferença aparente entre chamar um método de extensão e os métodos realmente definidos em um tipo.

...

Em geral, recomendamos que você implemente métodos de extensão com moderação e somente quando for necessário. Sempre que possível, o código do cliente que deve estender um tipo existente deve fazê-lo criando um novo tipo derivado do tipo existente. Para mais informações, consulte Herança.

Ao usar um método de extensão para estender um tipo cujo código-fonte não pode ser alterado, você corre o risco de que uma alteração na implementação do tipo faça com que seu método de extensão seja interrompido.

Se você implementar métodos de extensão para um determinado tipo, lembre-se dos seguintes pontos:

  • Um método de extensão nunca será chamado se tiver a mesma assinatura que um método definido no tipo.
  • Os métodos de extensão são colocados no escopo no nível do espaço para nome. Por exemplo, se você tiver várias classes estáticas que contenham métodos de extensão em um único namespace nomeado Extensions, todas elas serão colocadas no escopo pela using Extensions;diretiva.

Para resumir, os métodos de extensão são projetados para adicionar métodos de instância a um tipo específico, mesmo quando os desenvolvedores não podem fazê-lo diretamente. E como os métodos de instância sempre substituem os métodos de extensão, se presentes (se chamados usando a sintaxe do método de instância), isso deve ser feito se você não puder adicionar diretamente um método ou estender a classe. *

Em outras palavras, um método de extensão deve agir como um método de instância, porque pode acabar sendo um método de instância por algum cliente. E como um método de instância deve ser lançado se o objeto no qual está sendo chamado for null, o método de extensão também deve ser.


* Como observação lateral, esta é exatamente a situação que os designers do LINQ enfrentaram: quando o C # 3.0 foi lançado, já havia milhões de clientes que estavam usando System.Collections.IEnumerablee System.Collections.Generic.IEnumerable<T>, tanto em suas coleções quanto em foreachloops. Essas classes retornou IEnumeratorobjetos que só tinham os dois métodos Currente MoveNext, por isso, a adição de quaisquer métodos de instância necessárias adicionais, como Count, Any, etc., seria quebrar esses milhões de clientes. Portanto, para fornecer essa funcionalidade (especialmente porque ela pode ser implementada em termos de Currente MoveNextcom relativa facilidade), eles a lançaram como métodos de extensão, que podem ser aplicados a qualquer atualmente existenteIEnumerableinstância e também pode ser implementado por classes de maneiras mais eficientes. Se os designers do C # decidissem liberar o LINQ no primeiro dia, ele seria fornecido como método de instância IEnumerablee provavelmente projetariam algum tipo de sistema para fornecer implementações de interface padrão desses métodos.

TheHansinator
fonte
0

Acho que o ponto mais importante aqui é que, retornando false, em vez de lançar uma exceção, você está ofuscando informações que podem ser relevantes para futuros leitores / modificadores do seu código.

Se for possível que a lista seja nula, sugiro ter um caminho lógico separado para isso; caso contrário, no futuro, alguém poderá adicionar alguma lógica baseada em lista (como uma adição) ao resto {} do seu if, resultando em um exceção indesejada que eles não tinham motivos para prever.

A legibilidade e a manutenção superam 'Eu tenho que escrever uma condição extra' toda vez.

Callum Bradbury
fonte
0

Como regra geral, escrevo a maior parte do meu código para assumir que o chamador é responsável por não me fornecer dados nulos, principalmente pelos motivos descritos em Diga não ao nulo (e outras postagens semelhantes). O conceito de nulo geralmente não é bem compreendido e, por esse motivo, é aconselhável inicializar suas variáveis ​​antes do tempo, tanto quanto possível. Supondo que você esteja trabalhando com uma API razoável, o ideal é que você nunca recupere um valor nulo, portanto nunca precisará procurar nulo. O ponto nulo, como outras respostas indicaram, é garantir que você tenha um objeto válido (por exemplo, uma "bolsa") para trabalhar antes de continuar. Este não é um recurso do Any, mas um recurso do idiomaem si. Você não pode executar a maioria das operações em um objeto nulo, porque ele não existe. É como se eu pedisse para você dirigir até a loja do meu carro, exceto que eu não tenho carro, então você não tem como usar o meu carro para ir até a loja. Não faz sentido executar uma operação em algo que literalmente não existe.

Existem casos práticos para o uso de nulo, como quando você literalmente não tem as informações solicitadas disponíveis (por exemplo, se eu lhe perguntar qual é a minha idade, a opção mais provável para você responder nesse momento é "Eu não sei"). ", que é o valor nulo). No entanto, na maioria dos casos, você deve pelo menos saber se suas variáveis ​​foram inicializadas ou não. E se não o fizer, recomendo que você reforce seu código. A primeira coisa que faço em qualquer programa ou função é inicializar um valor antes de usá-lo. É raro precisar verificar valores nulos, pois posso garantir que minhas variáveis ​​não sejam nulas. É um bom hábito entrar, e quanto mais você se lembrar de inicializar suas variáveis, menos frequentemente você precisa verificar se há nulo.

phyrfox
fonte