¿No es razonable esperar que Any () * no * arroje una excepción de referencia nula?

41

Cuando crea un método de extensión, puede, por supuesto, llamarlo. nullPero, a diferencia de una llamada al método de instancia, llamarlo como nulo no tiene que arrojar un NullReferenceException-> debe verificarlo y hacerlo manualmente.

Para la implementación del método de extensión Linq, Any()Microsoft decidió que deberían lanzar un ArgumentNullException( https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/AnyAll.cs ).

Me molesta tener que escribir if( myCollection != null && myCollection.Any() )

¿Estoy equivocado, como cliente de este código, al esperar que, por ejemplo ((int[])null).Any(), vuelva false?

esto se extiende
fuente
41
en C # 6, puede simplificar su cheque a if (myCollection? .Any () == true)
17 de 26
55
Incluso en F #, que realmente no utiliza valores nulos, excepto la interoperabilidad con otros lenguajes .NET, null |> Seq.isEmptyarroja System.ArgumentNullException: Value cannot be null. La expectativa parece ser que no pasará valores indefinidos para algo que se espera que exista, por lo que sigue siendo una excepción cuando tiene un valor nulo. Si es una cuestión de inicialización, comenzaría con una secuencia vacía en lugar de a null.
Aaron M. Eshbach
21
Es por eso que no debe regresar nullcuando se trata de colecciones, sino que debe usar una colección vacía en esos casos.
Bakuriu
31
Bueno, ¿por qué es nulo en primer lugar? No desea que nulo se cuente como vacío, porque no está vacío, es algo completamente diferente. Tal vez desee que se cuente como vacío en su caso, pero agregar ese tipo de cosas al lenguaje genera errores.
user253751
22
Debo señalar que cada método LINQ arroja un argumento nulo. AnyEs simplemente consistente.
Sebastian Redl

Respuestas:

157

Tengo una bolsa con cinco papas. ¿Hay .Any()papas en la bolsa?

" ", dices.<= true

Saco todas las papas y las como. ¿Hay .Any()papas en la bolsa?

" No ", dices.<= false

Incinero completamente la bolsa en un incendio. ¿Hay .Any()papas en la bolsa ahora?

" No hay bolsa ".<= ArgumentNullException

Dan Wilson
fuente
3
Pero al vacío, ¿no hay papas en la bolsa? Falso implica Falso ... (No estoy en desacuerdo, solo una segunda perspectiva).
D. Ben Knoble
66
Más prácticamente, alguien le entrega una caja cerrada de una fuente desconocida. ¿La bolsa en la caja contiene papas? Solo estoy interesado en 2 escenarios: A) hay una bolsa en la caja que contiene papas, o B) no hay papas y / o no hay bolsa en la caja. Semánticamente, sí, hay una diferencia entre nulo y vacío, pero el 99% de las veces no me importa.
Dave Thieben
66
¿Comiste cinco papas crudas? Busque atención médica de inmediato.
Oly
3
@Oly Dan los cocinó en el fuego, antes de comer y usar ese fuego para incinerar la bolsa.
Ismael Miguel
3
@ D.BenKnoble: Sin haber visto la cajuela de mi auto, ¿estás dispuesto a testificar que no hay cuerpos en la cajuela de mi auto? ¿No? ¿Cuál es la diferencia entre verificar el tronco y no encontrar nada, o no verificar el tronco? ¿No puede simplemente testificar ahora, ya que habría visto exactamente la misma cantidad de cuerpos en cualquier caso? ... Esa es la diferencia. No puedes responder por algo si no puedes confirmarlo en primer lugar. Asumes que los dos son equiparables, pero eso no es un hecho. En algunos casos, puede haber una diferencia importante entre los dos.
Flater
52

En primer lugar, parece que ese código fuente arrojará ArgumentNullException, no NullReferenceException.

Una vez dicho esto, en muchos casos ya sabe que su colección no es nula, porque este código solo se llama desde el código que sabe que la colección ya existe, por lo que no tendrá que colocar la verificación nula allí con mucha frecuencia. Pero si no sabe que existe, entonces tiene sentido verificar antes de llamarlo Any().

¿Estoy equivocado, como cliente de este código, al esperar que, por ejemplo ((int[])null).Any(), vuelva false?

Sí. La pregunta que Any()responde es "¿esta colección contiene algún elemento?" Si esta colección no existe, entonces la pregunta en sí misma no tiene sentido; no puede contener ni no contener nada, porque no existe.

Mason Wheeler
fuente
18
@ChrisWohlert: Tu intuición me intriga. ¿También cree que semánticamente, una persona inexistente es una persona vacía, cuyo nombre es la cadena vacía y la edad es cero y así sucesivamente? ¿Y crees que un conjunto que contiene nulles equivalente a un conjunto que contiene el conjunto vacío (y viceversa)?
ruakh
17
@ChrisWohlert: Obviamente, un conjunto puede contener el conjunto vacío; pero parece creer eso { null }y { {} }debería ser equivalente. Me parece fascinante; No puedo relacionarme con eso en absoluto.
ruakh
99
¿Debería crear .Adduna nullcolección de alguna manera para nosotros también?
Mateo
13
@ChrisWohlert "A es un conjunto vacío B es un conjunto que contiene una sandía es una vaciar Sí es B es C vaciar Nº vaciar Uhhh .....?.??"
user253751
16
Punto pedagógico: no es el caso de que, en teoría de conjuntos, un conjunto no existente sea un conjunto vacío. El conjunto vacío existe, y cualquier conjunto no existente no lo es (y de hecho, no es nada en absoluto, ya que no existe).
James_pic
22

Nulo significa información faltante, no elementos.

Podría considerar más ampliamente evitar nulos; por ejemplo, use uno de los enumerables vacíos incorporados para representar una colección sin elementos en lugar de nulo.

Si devuelve nulo en algunas circunstancias, puede cambiar eso para devolver la colección vacía. (De lo contrario, si encuentra nulos devueltos por métodos de biblioteca (no los suyos), eso es desafortunado, y los envolvería para normalizar).

Ver también https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty

Erik Eidt
fuente
1
Eso nullno significa que ningún elemento es cuestión de utilizar una convención sensata. Basta con pensar en OLESTRINGS nativas, donde realmente hace decir eso.
Deduplicador
1
@Deduplicator, ¿estás hablando de la posibilidad de vinculación e incrustación de objetos de Microsoft? Si es así, recordemos que OLE es de los años 90. Mirando más actualmente, muchos lenguajes modernos (C #, Java, Swift) están proporcionando instalaciones para eliminar / erradicar los usos de nulo.
Erik Eidt
2
@ErikEidt Lo están haciendo, en parte, porque nullno significa "información faltante". nullno tiene una sola interpretación significativa. En cambio, es una cuestión de cómo lo tratas. nulla veces se usa para "información faltante", pero también para "sin elementos", y también para "se produjo un error" o "información no inicializada" o "información conflictiva" o alguna cosa arbitraria y ad-hoc.
Derek Elkins
-1. Esta es una decisión tomada por el desarrollador, no por teorías abstractas. nullse usa con mucha frecuencia para significar "sin datos". A veces tiene sentido. Otras veces no.
jpmc26
13

Aparte de la sintaxis condicional nula , hay otra técnica para aliviar este problema: no permita que su variable permanezca null.

Considere una función que acepta una colección como parámetro. Si a los efectos de la función, nully vacío son equivalentes, puede asegurarse de que nunca contenga nullal principio:

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

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

Puede hacer lo mismo cuando busca colecciones de algún otro método:

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

(Tenga en cuenta que en los casos en los que tiene control sobre una función como GetWordsy nulles equivalente a la colección vacía, es preferible devolver la colección vacía en primer lugar).

Ahora puede realizar cualquier operación que desee en la colección. Esto es especialmente útil si necesita realizar muchas operaciones que fallarían cuando la colección es null, y en los casos en que obtenga el mismo resultado al recorrer o consultar un enumerable vacío, permitirá eliminar las ifcondiciones por completo.

jpmc26
fuente
12

¿Estoy equivocado, como cliente de este código, al esperar que, por ejemplo, ((int []) null) .Any () devuelva falso?

Sí, simplemente porque estás en C # y ese comportamiento está bien definido y documentado.

Si estuviera haciendo su propia biblioteca, o si estuviera usando un idioma diferente con una cultura de excepción diferente, entonces sería más razonable esperar falso.

Personalmente, siento que return false es un enfoque más seguro que hace que su programa sea más robusto, pero al menos es discutible.

Telastyn
fuente
15
Esa 'robustez' a menudo es una ilusión: si el código que genera la matriz de repente comienza a generar NULL inesperadamente debido a un error u otro problema, su código 'robusto' ocultará el problema. Es un comportamiento apropiado a veces, pero no es un defecto seguro.
GoatInTheMachine
1
@GoatInTheMachine: no estoy de acuerdo con que sea un valor predeterminado seguro, pero tienes razón en que oculta el problema y que ese comportamiento es indeseable a veces. En mi experiencia, ocultar el problema (o confiar en las pruebas unitarias para detectar los problemas de otros códigos) es mejor que bloquear su aplicación lanzando excepciones inesperadas. Quiero decir realmente: si el código de llamada está lo suficientemente roto como para enviar nulos, ¿cuál es la posibilidad de que manejen las excepciones correctamente?
Telastyn
10
Si algo se rompe, ya sea mi código, el de otro colega o el de un cliente, preferiría que el código fallara de inmediato y la gente lo supiera de lo que continuó en un estado potencialmente inconsistente durante un período de tiempo indeterminado. Ser capaz de hacer esto es, por supuesto, a veces un lujo y no siempre apropiado, pero es el enfoque que prefiero.
GoatInTheMachine
1
@GoatInTheMachine: estoy de acuerdo con muchas cosas, pero las colecciones tienden a ser diferentes. Tratar nulo como una colección vacía no es un comportamiento terriblemente inconsistente o sorprendente.
Telastyn
8
Imagine que tiene una matriz que se completa a partir de un documento JSON recibido a través de una solicitud web, y en la producción uno de los clientes de su API de repente tiene un problema en el que envía a través de JSON parcialmente inválido lo que hace que deserialice una matriz como NULL, preferiría: el código, en el peor de los casos, arrojó una excepción de referencia NULL en el momento en que llegó la primera solicitud incorrecta, que vería en el registro e inmediatamente le dirá al cliente que arregle sus solicitudes rotas, O su código dice "oh, la matriz está vacía, nada ¡que hacer!" y silenciosamente escribió 'la cesta de compra no tenía artículos' al db durante unas semanas?
GoatInTheMachine
10

Si las comprobaciones nulas repetidas le molestan, puede crear su propio método de extensión 'IsNullOrEmpty ()', para reflejar el método String con ese nombre, y ajustar la llamada null-check y .Any () en una sola llamada.

De lo contrario, la solución, mencionada por @ 17 de 26 en un comentario bajo su pregunta, también es más corta que el método 'estándar' y razonablemente clara para cualquiera que esté familiarizado con la nueva sintaxis condicional nula.

if(myCollection?.Any() == true)
Theo Brinkman
fuente
44
También puedes usar en ?? falselugar de == true. Esto me parecería más explícito (más limpio) ya que maneja solo el caso de null, y en realidad no es más detallado. Además, los ==controles de booleanos generalmente desencadenan mi reflejo nauseoso. =)
jpmc26
2
@ jpmc26: No sé mucho sobre C #. ¿Por qué no es myCollection?.Any()suficiente?
Eric Duminil
66
@EricDuminil Debido a la forma en que funciona el operador condicional nulo, myCollection?.Any()devuelve efectivamente un booleano anulable en lugar de un booleano ordinario (es decir, bool? En lugar de bool). No hay conversión implícita de bool? bool, y es un bool que necesitamos en este ejemplo en particular (para probar como parte de la ifcondición). Por lo tanto, debemos comparar explícitamente trueo hacer uso del operador de fusión nula (??).
Steven Rands
@ jpmc26 ?? falso es más difícil de leer que myCollection? .Any () == verdadero. Independientemente de su reflejo nauseoso, == verdadero es lo que está intentando probar implícitamente. ?? falso solo agrega ruido adicional y aún necesita hacer la evaluación en su cabeza sobre lo que sucede si nulo, ese nulo == verdadero fallaría, casi sin que el lector tenga que ser consciente de ello ?..
Ryan The Leach
2
@RyanTheLeach Tengo que pensar mucho más si ==realmente funcionará. Ya sé lo que sucede con un booleano intuitivamente cuando solo puede ser trueo false; Ni siquiera tengo que pensarlo. Pero tírelo nulla la mezcla, y ahora tengo que averiguar si eso ==es correcto. ??en su lugar, simplemente elimina el nullcaso, reduciéndolo de nuevo a truey false, que ya comprende de inmediato. En cuanto a mi reflejo nauseoso, cuando lo veo por primera vez, mi instinto inmediato es simplemente eliminarlo, ya que generalmente es inútil, lo que no quieres que suceda.
jpmc26
8

¿Estoy equivocado, como cliente de este código, al esperar que, por ejemplo, ((int []) null) .Any () devuelva falso?

Si te preguntas sobre las expectativas, debes pensar en las intenciones.

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

Como se menciona en la respuesta de Erik Eidt , hay una diferencia de significado entre nully una colección vacía.

Echemos un primer vistazo a cómo se supone que deben usarse.

El libro Framework Design Guidelines: Convenciones, modismos y patrones para bibliotecas .NET reutilizables, segunda edición, escrito por los arquitectos de Microsoft Krzysztof Cwalina y Brad Abrams establece la siguiente mejor práctica:

X NO devuelva valores nulos de propiedades de colección o de métodos que devuelven colecciones. Devuelve una colección vacía o una matriz vacía en su lugar.

Considere llamar a un método que finalmente obtiene datos de una base de datos: si recibe una matriz vacía o Enumerable.Empty<T>esto simplemente significa que su espacio de muestra está vacío, es decir, su resultado es un conjunto vacío . nullSin embargo, recibir en este contexto significaría un estado de error .

En la misma línea de pensamiento que la analogía de la papa de Dan Wilson , tiene sentido hacer preguntas sobre sus datos, incluso si se trata de un conjunto vacío . Pero tiene mucho menos sentido, si no hay un conjunto .

Søren D. Ptæus
fuente
1
Si tienen significados diferentes depende en gran medida del contexto. A menudo, a los efectos de cualquier lógica que tengan a mano, representan conceptos equivalentes. No siempre , pero a menudo.
jpmc26
1
@ jpmc26: Creo que el objetivo de esta respuesta es decir que al codificar las pautas para c # tienen un significado diferente. Siempre puede corregir el código donde nulo y vacío son iguales si lo desea. Y en algunos casos también puede hacer lo mismo, ya sea nulo o vacío, pero eso no significa que signifiquen lo mismo.
Chris
@Chris Y digo que las pautas de codificación de las personas que diseñaron el lenguaje no se pueden usar como un reemplazo para evaluar su código en el contexto de sus requisitos, las bibliotecas que está usando y los otros desarrolladores con los que trabaja. La idea de que nunca serán equivalentes en su contexto es el idealismo de pastel en el cielo. Puede que incluso no sean equivalentes para los datos disponibles en general, sino que sean equivalentes para generar un resultado en alguna función específica que esté escribiendo; en ese caso, debe admitir ambos, pero asegurarse de que generen el mismo resultado.
jpmc26
Puedo estar confundido por lo que está diciendo, pero cuando nulo y vacío son equivalentes para generar un resultado, no veo por qué no usaría separadamente, es nulo y está vacío, en lugar de querer un método que haga ambas cosas a la vez, pero no te permite distinguirlos en otras situaciones ...
Chris
@ Chris Me refiero a tener diferentes contextos (que a menudo corresponden a ámbitos). Considere una función por ejemplo. nully vacío puede resultar en el mismo valor de retorno para la función, pero eso no significa que nully vacío significa exactamente lo mismo en el alcance de la llamada.
jpmc26
3

Hay muchas respuestas que explican por qué nully las vacías son diferentes y suficientes opiniones que intentan explicar por qué deben tratarse de manera diferente o no. Sin embargo, estás preguntando:

¿Estoy equivocado, como cliente de este código, al esperar que, por ejemplo, ((int []) null) .Any () devuelva falso?

Es una expectativa perfectamente razonable . Tienes tanta razón como alguien más que defiende el comportamiento actual. Estoy de acuerdo con la filosofía de implementación actual, pero los factores impulsores no se basan únicamente en consideraciones fuera de contexto.

Dado que Any()sin predicado es esencialmente Count() > 0, ¿qué esperas de este fragmento?

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

O un genérico:

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

Supongo que esperas NullReferenceException.

  • Any()es un método de extensión, debe integrarse sin problemas con el objeto extendido y luego lanzar una excepción es lo menos sorprendente.
  • No todos los lenguajes .NET admiten métodos de extensión.
  • Siempre puedes llamar Enumerable.Any(null)y allí definitivamente lo esperas ArgumentNullException. Es el mismo método y tiene que ser coherente con, posiblemente, casi TODO lo demás en el Marco.
  • Acceder a un nullobjeto es un error de programación , el marco no debe aplicar nulo como valor mágico . Si lo usa de esa manera, es su responsabilidad tratarlo.
  • Es obstinado , piensas de una manera y yo pienso de otra manera. El marco debe ser tan discreto como sea posible.
  • Si tiene un caso especial, debe ser coherente : debe tomar decisiones cada vez más obstinadas sobre todos los demás métodos de extensión: si Count()parece una decisión fácil, entonces Where()no lo es. ¿Qué hay de Max()? Lanza una excepción para una lista VACÍA, ¿no debería arrojar también para una null?

Lo que los diseñadores de la biblioteca hicieron antes de LINQ fue introducir métodos explícitos cuando nulles un valor válido (por ejemplo String.IsNullOrEmpty()) y luego TENÍAN que ser consistentes con la filosofía de diseño existente . Dicho esto, incluso si es bastante trivial de escribir, dos métodos EmptyIfNull()y EmptyOrNull()podrían ser útiles.

Adriano Repetti
fuente
1

Se supone que Jim debe dejar papas en cada bolsa. De lo contrario, lo voy a matar.

Jim tiene una bolsa con cinco papas. ¿Hay .Any()papas en la bolsa?

"Sí", dices. <= verdadero

Ok, entonces Jim vive esta vez.

Jim saca todas las papas y se las come. ¿Hay alguna () papa en la bolsa?

"No", dices. <= falso

Hora de matar a Jim.

Jim incinera completamente la bolsa en un incendio. ¿Hay alguna () papa en la bolsa ahora?

"No hay bolsa". <= ArgumentNullException

¿Debería Jim vivir o morir? Bueno, no esperábamos esto, así que necesito una decisión. ¿Dejar que Jim se salga con la suya es un error o no?

Puede usar anotaciones para indicar que no está soportando ninguna travesura nula de esta manera.

public bool Any( [NotNull] List bag ) 

Pero su cadena de herramientas tiene que soportarlo. Lo que significa que probablemente terminarás escribiendo cheques.

naranja confitada
fuente
0

Si esto te molesta tanto, te sugiero un método de extensión simple.

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

Ahora puedes hacer esto:

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

... y la bandera se establecerá en false.

John Wu
fuente
2
Más natural escribir la returndeclaración como:return source ?? Enumerable.Empty<T>();
Jeppe Stig Nielsen
Esto no responde la pregunta formulada.
Kenneth K.
@ KennethK. Pero parece resolver el problema presentado.
RQDQ
0

Esta es una pregunta sobre los métodos de extensión de C # y su filosofía de diseño, por lo que creo que la mejor manera de responder a esta pregunta es citar la documentación de MSDN sobre el propósito de los métodos de extensión :

Los métodos de extensión le permiten "agregar" métodos a los tipos existentes sin crear un nuevo tipo derivado, volver a compilar o modificar el tipo original. Los métodos de extensión son un tipo especial de método estático, pero se llaman como si fueran métodos de instancia en el tipo extendido. Para el código de cliente escrito en C #, F # y Visual Basic, no existe una diferencia aparente entre llamar a un método de extensión y los métodos que realmente están definidos en un tipo.

...

En general, le recomendamos que implemente los métodos de extensión con moderación y solo cuando sea necesario. Siempre que sea posible, el código del cliente que debe extender un tipo existente debe hacerlo creando un nuevo tipo derivado del tipo existente. Para obtener más información, vea Herencia.

Cuando utiliza un método de extensión para extender un tipo cuyo código fuente no puede cambiar, corre el riesgo de que un cambio en la implementación del tipo haga que su método de extensión se rompa.

Si implementa métodos de extensión para un tipo dado, recuerde los siguientes puntos:

  • Nunca se llamará a un método de extensión si tiene la misma firma que un método definido en el tipo.
  • Los métodos de extensión se incorporan al nivel del espacio de nombres. Por ejemplo, si tiene varias clases estáticas que contienen métodos de extensión en un solo espacio de nombres con nombre Extensions, la using Extensions;directiva los incluirá a todos .

Para resumir, los métodos de extensión están diseñados para agregar métodos de instancia a un tipo particular, incluso cuando los desarrolladores no pueden hacerlo directamente. Y debido a que los métodos de instancia siempre anularán los métodos de extensión si están presentes (si se llama utilizando la sintaxis del método de instancia), esto solo debe hacerse si no puede agregar directamente un método o extender la clase. *

En otras palabras, un método de extensión debería actuar exactamente como lo haría un método de instancia, porque puede terminar siendo un método de instancia por algún cliente. Y debido a que un método de instancia debería arrojar si el objeto al que se está llamando es null, también debería hacerlo el método de extensión.


* Como nota al margen, esta es exactamente la situación que enfrentaron los diseñadores de LINQ: cuando se lanzó C # 3.0, ya había millones de clientes que usaban System.Collections.IEnumerabley System.Collections.Generic.IEnumerable<T>, tanto en sus colecciones como en foreachbucles. Estas clases volvieron IEnumeratorobjetos que sólo tenían los dos métodos Currenty MoveNext, por lo que añadir cualquiera de los métodos instancia necesarios adicionales, tales como Count, Any, etc., sería romper estos millones de clientes. Entonces, para proporcionar esta funcionalidad (especialmente porque se puede implementar en términos de Currenty MoveNextcon relativa facilidad), la lanzaron como métodos de extensión, que se pueden aplicar a cualquier sistema existente actualmente.IEnumerableinstancia y también puede ser implementado por clases de maneras más eficientes. Si los diseñadores de C # hubieran decidido lanzar LINQ el primer día, se habrían proporcionado como métodos de instancia IEnumerabley probablemente habrían diseñado algún tipo de sistema para proporcionar implementaciones de interfaz predeterminadas de esos métodos.

TheHansinator
fuente
0

Creo que el punto principal aquí es que al devolver falso en lugar de lanzar una excepción, está ofuscando información que puede ser relevante para futuros lectores / modificadores de su código.

Si es posible que la lista sea nula, sugeriría tener una ruta lógica separada para eso, ya que de lo contrario en el futuro alguien puede agregar alguna lógica basada en la lista (como un complemento) al else {} de su if, lo que resulta en un excepción no deseada que no tenían razón para predecir.

La legibilidad y la mantenibilidad triunfan 'Tengo que escribir una condición adicional' cada vez.

Callum Bradbury
fuente
0

Como regla general, escribo la mayor parte de mi código para suponer que la persona que llama es responsable de no entregarme datos nulos, principalmente por los motivos descritos en Di no a nulo (y otras publicaciones similares). El concepto de nulo a menudo no se comprende bien y, por esa razón, es aconsejable inicializar sus variables con anticipación, tanto como sea práctico. Suponiendo que está trabajando con una API razonable, idealmente nunca debería recuperar un valor nulo, por lo que nunca debería tener que verificar si es nulo. El punto nulo, como han dicho otras respuestas, es asegurarse de que tiene un objeto válido (por ejemplo, una "bolsa") para trabajar antes de continuar. Esto no es una característica de Any, sino una característica del lenguajesí mismo. No puede realizar la mayoría de las operaciones en un objeto nulo, porque no existe. Es como si te pido que conduzcas a la tienda en mi automóvil, excepto que no tengo un automóvil, por lo que no tienes forma de usar mi automóvil para conducir a la tienda. No tiene sentido realizar una operación en algo que literalmente no existe.

Hay casos prácticos para usar nulo, como cuando literalmente no tiene la información solicitada disponible (por ejemplo, si le pregunto cuál es mi edad, la opción más probable para que responda en este momento es "No sé ", que es lo que es un valor nulo). Sin embargo, en la mayoría de los casos, al menos debe saber si sus variables se inicializan o no. Y si no lo hace, le recomendaría que necesita ajustar su código. Lo primero que hago en cualquier programa o función es inicializar un valor antes de usarlo. Es raro que necesite verificar valores nulos, porque puedo garantizar que mis variables no son nulas. Es un buen hábito, y cuanto más se acuerde de inicializar sus variables, con menos frecuencia deberá comprobar si hay valores nulos.

phyrfox
fuente