has - .NET DBNull vs Nothing en todos los tipos de variables?
referenced object has a value of nothing (6)
Estoy un poco confundido acerca de valores nulos y variables en .NET. (VB preferido)
¿Hay alguna forma de verificar la "nulidad" de CUALQUIER variable dado independientemente de si se trata de un objeto o un tipo de valor? ¿O mi verificación nula debe anticipar siempre si está comprobando un tipo de valor (por ejemplo, System.Integer) o un objeto?
Creo que lo que estoy buscando es una función que verifica todo tipo de nulidad posible. Es decir, cualquier tipo de variables que
a) nunca se le asignó un valor desde que se declaró
b) se les asignó un valor nulo de un objeto de datos (que provenía de una base de datos)
c) se establecieron iguales a otro valor variable que era nulo
d) se establecieron en una variable de aplicación / sesión ASP.NET que nunca se estableció o expiró.
¿Existe una mejor práctica general cuando se trata de manejar escenarios nulos en .NET?
ACTUALIZACIÓN: cuando hablo de que un tipo de valor es "nulo", lo que realmente quiero decir es un tipo de valor que nunca se estableció o que en algún momento se estableció igual o se emitió desde un objeto nulo.
¿Es esto lo que buscas?
if IsNothing(foo) OrElse IsDbNull(foo) Then
'' Do Something Because foo Is Either Nothing or DBNull.Value
End If
En verdad, no estoy seguro de por qué desearías esta estructura. La única vez que comprobaría DBNULL.Value es cuando estoy usando valores que provienen de una base de datos, y antes de asignar dicho valor de una clase DATA Namespace a alguna otra clase [ie dim b como string = dataReader (0) ]
Por lo general, si le preocupa que un objeto no se haya instanciado o necesite que se vuelva a crear una instancia, bastará con una comprobación IsNothing.
En .Net, son solo dos tipos de nulos que conozco, nulos (nada en VB) y DbNull. Si usa un System.Nullable, puede usar la misma sintaxis de comprobación nula que con un objeto. Si su objeto anulable está encuadrado, .Net 2.0 CLR es lo suficientemente inteligente como para descubrir la forma correcta de manejarlo.
El único caso en el que me he encontrado con ambos tipos es en el nivel de datos de una aplicación en la que podría acceder directamente a los datos de la base de datos. Por ejemplo, me he encontrado con DbNull en una DataTable. Para verificar estos dos tipos de nulos en esta ubicación, podría escribir un método de extensión como (lo siento, en C #):
static public bool IsNull(this object obj)
{
return obj != null && obj != DbNull.Value;
}
...
if(dataTable[0]["MyColumn"].IsNull())
{
//do something
}
Las variables de tipo de valor no pueden contener nulo, eso es porque lo nulo significa, nulo significa que las referencias no apuntan a ninguna parte. No sé en VB.net pero en c # puede envolver los tipos de valor para que sean nulables usando el "?", Como:
int? a = null;
Los tipos de valores no pueden ser nulos. Viola lo que significa ser un tipo de valor. Puede ajustar Value Types como Nullable (Of T), que le proporciona un gran conjunto de métodos, y las comprobaciones de Nothing funcionan. Pero tienes mucho sobrecarga con esa envoltura. Tal vez puedas aclarar lo que intentas hacer?
Para completar, la sintaxis de VB para envoltorios Nullable es:
Dim i as Nullable(Of Integer) = Nothing ''.NET 2.0/3.0''
Dim j as Integer? = Nothing ''.NET 3.5''
EDITAR: el tipo de valor siempre está preinicializado en un valor predeterminado, 0 para los valores numéricos, falso para los elementos booleanos, etc.
Los tipos de valores normales (booleanos, ints, longs, float, double, enum y structs) no son anulables.
El valor predeterminado para todos los tipos de valores es 0.
El CLR no le permitirá acceder a las variables a menos que se hayan establecido. Puede pensar que este no es siempre el caso, pero a veces el CLR interviene y los inicializa por usted. En un nivel de método, debe inicializar explícitamente todas las variables antes de que se utilicen.
Además, como otros señalan, desde .net 2.0 hay un nuevo tipo genérico llamado Nullable<T>
. Hay algunos shorthands de compilador en C # como int? significa Nullable<int>
, ¿doble? significa Nullable<double>
etc.
Solo puede ajustar Nullable<T>
sobre tipos de valores que no aceptan valores de nulos, lo que está bien ya que las referencias ya tienen la capacidad de ser nulas.
int? x = null;
Para un int ?, mientras puede probar contra null, a veces es mejor llamar a x.HasValue()
.
¿En C # también está el operador que se puede unir ? cuando desee asignar un tipo de valor que admite nulos a un valor que no admite nulos. Pero si no tiene el operador, puede llamar a GetValueOrDefault ().
int y = x ?? 2; // y becomes 2 if x is null.
int z = x.GetValueOrDefault(2); // same as y
Mientras desarrolle con Option Strict On, (a) no debería ser un problema. El compilador te gritará. Si te preocupa comprobar los parámetros, solo usa
Public Sub MySub(ByVal param1 as MyObject, ByVal param2 as Integer)
if param1 is nothing then
Throw New ArgumentException("param1 cannot be null!")
end if
''param2 cannot be null
End Sub
Para (b), su capa de interacción con la base de datos debe manejar esto. Si está utilizando LINQ, hay formas de manejar esto. Si está utilizando conjuntos de datos tipados, existe una propiedad .IsMyVariableNull en la fila que se genera automáticamente.
Para (c), no necesita preocuparse por los tipos de valores, pero los tipos de referencia se pueden verificar con un simple Is Nothing (o Is Nothing Nothing).
Para (d), puede aplicar la misma lógica después de la lectura. Pruebe la variable receptora contra Nothing.
En su mayor parte, un simple control de Is Nothing te ayudará. La capa de interacción de la base de datos le ayudará a manejar el caso más complicado de valores nulos en sus datos, pero depende de usted manejarlos de manera adecuada.