Este escrito ha sido aprobado por expertos para asegurar la veracidad de nuestra esta reseña.
Solución:
Voy a estar en desacuerdo con la tendencia aquí. Dejaré constancia:
no estoy de acuerdo con eso
DBNull
sirve para cualquier propósito útil; agrega confusión innecesaria, mientras que prácticamente no aporta ningún valor.
A menudo se presenta el argumento de que null
es una referencia inválida, y que DBNull
es un null patrón de objeto; tampoco es true. Por ejemplo:
int? x = null;
esta no es una “referencia inválida”; es un null
valor. En efecto null
significa lo que quieras que signifique y, francamente, no tengo ningún problema en trabajar con valores que pueden ser null
(de hecho, incluso en SQL necesitamos trabajar correctamente con null
– nada cambia aquí). Igualmente, el “null patrón de objeto” solo tiene sentido si realmente lo está tratando como un objeto en términos de programación orientada a objetos, pero si tenemos un valor que puede ser “nuestro valor, o un DBNull
“entonces debe ser object
por lo que no podemos estar haciendo nada útil con él.
Hay tantas cosas malas con DBNull
:
- te obliga a trabajar con
object
ya que soloobject
puede aguantarDBNull
o otro valor - no hay una diferencia real entre “podría ser un valor o
DBNull
” vs “podría ser un valor onull
“ - el argumento de que se deriva de 1.1 (tipos pre-anulables) no tiene sentido; podríamos usar
null
perfectamente bien en 1.1 - la mayoría de las API tienen “¿es null?” métodos, por ejemplo
DBDataReader.IsDBNull
oDataRow.IsNull
– ninguno de los cuales realmente requiereDBNull
existir en términos de la API DBNull
falla en términos de null-coalescente;value ?? defaultValue
no funciona si el valor esDBNull
DBNull.Value
no se puede usar en parámetros opcionales, ya que no es una constante- la semántica del tiempo de ejecución de
DBNull
son idénticas a la semántica denull
; en particular,DBNull
en realidad es igualDBNull
– por lo que no es hacer el trabajo de representar la semántica SQL - a menudo obliga a los valores de tipo de valor a encuadrarse ya que usa en exceso
object
- si necesita probar
DBNull
también podría haber probado solonull
- causa grandes problemas para cosas como parámetros de comando, con un comportamiento muy tonto que si un parámetro tiene un
null
valor no se envía… bueno, aquí hay una idea: si no desea que se envíe un parámetro – no lo agregue a la colección de parámetros - cada ORM en el que puedo pensar funciona perfectamente bien sin ninguna necesidad o uso de
DBNull
excepto como una molestia adicional al hablar con el código ADO.NET
Lo único incluso remotamente argumento convincente que tengo alguna vez visto para justificar la existencia de tal valor está en DataTable
, al pasar valores para crear una nueva fila; un null
significa “usar el predeterminado”, un DBNull
es explícitamente un null – francamente esta API podría haber tenido un tratamiento específico para este caso – un imaginario DataRow.DefaultValue
por ejemplo, sería mucho mejor que introducir un DBNull.Value
que infecta grandes extensiones de código sin ningún motivo.
Igualmente, el ExecuteScalar
el escenario es… tenue en el mejor de los casos; si está ejecutando un método escalar, esperar un resultado. En el escenario donde no hay filas, regresando null
no parece demasiado terrible. Si es absolutamente necesario eliminar la ambigüedad entre “sin filas” y “una sola null devuelto”, está la API del lector.
Este barco zarpó hace mucho tiempo y es demasiado tarde para arreglarlo. ¡Pero! Por favor, hazlo no Creo que todos están de acuerdo en que esto es algo “obvio”. Muchos desarrolladores lo hacen no vea el valor en esta extraña arruga en el BCL.
De hecho, me pregunto si todo esto se debe a dos cosas:
- tener que usar la palabra
Nothing
en lugar de algo que involucre “null” en VB - pudiendo nosotros el
if(value is DBNull)
sintaxis que “se parece a SQL”, en lugar de la tan complicadaif(value==null)
Resumen:
Tener 3 opciones (null
, DBNull
, o un valor real) solo es útil si hay un ejemplo genuino en el que necesita eliminar la ambigüedad entre 3 casos diferentes. Todavía tengo que ver una ocasión en la que necesito representar a dos diferentes “null” afirma, por lo que DBNull
es completamente redundante dado que null
ya existe y tiene mucho mejor lenguaje y soporte de tiempo de ejecución.
El punto es que en ciertas situaciones hay una diferencia entre un valor de base de datos null y un .NET nulo.
Por ejemplo. Si usa ExecuteScalar (que devuelve la primera columna de la primera fila en el conjunto de resultados) y obtiene un null atrás eso significa que el SQL ejecutado no devolvió ningún valor. Si recupera DBNull, significa que el SQL devolvió un valor y era NULL. Tienes que ser capaz de notar la diferencia.
DbNull
representa una caja sin contenido; null
indica la inexistencia de la caja.