¿Por qué no puedo usar '??'? operando para system.dbnull valor?
Pregunta
Tengo una tabla de datos de Oracle que busca columnas que son nulas.Así que, para mantener el código agradable y simple, usaría el comando ??operando.AlternatePhoneNumber es una cadena en mi modelo de C#.
AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""
Sin embargo, incluso con ese código sigo recibiendo el error.
System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
Sé lo que significa el error, pero ¿por qué?¿No se puede utilizar en DBNull?¿No son null y DBNull esencialmente lo mismo?
Gracias.
Solución
El ??
operador sólo se aplica a la realidad null
s.
null
y DBNull.Value
no son lo mismo; DBNull.Value
es simplemente un objeto marcador de posición.
Además, esa excepción proviene del interior del AlternatePhoneNumber
propiedad, antes de su ??
el operador ejecuta.(Su código no tiene conversión).
Si customer
es una fila en un conjunto de datos escrito, cambie la columna NullValue
propiedad en el diseñador.
Otros consejos
null y dbnull no son lo mismo.System.dbnull es un objeto real.
El problema es que AlternatePhoneNumber
es una cadena.Dbnull no es.
Intente esto en lugar:
AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
Haga esto:
public T IfNull<T>(object o, T value)
{
return (o == DbNull.Value) ? value : (T)o;
}
DBNull es un tipo con un valor único y no es lo mismo que una referencia de cadena nula, por lo que no se puede utilizar ??
.Podrías hacer esto sin embargo:
string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
Como otro estado de respuestas, null
significa una referencia que no se refiere a ningún objeto, mientras que DBNull
es una clase suministrada por ADO.NET a Indica cuando un campo o valor es nulo en la base de datos (o enun datatable).
Mientras puede usar el Operador condicional (ternario)(? :) para hacer lo que quieres:
AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull
? ""
: customer.AlternatePhoneNumber;
Tiendo a envolver esto en una Método de extensión :
static class NullExtensions
{
public static T WhenNull<T>( this object value, T whenNullValue )
{
return (value == null || value is DBNull)
? whenNullValue
: (T)value;
}
}
que encuentro hace que el código sea más fácil de leer y entender.
AlternatePhoneNumber = customer.AlternatePhoneNumber.WhenNull( "" );
dbnull no es un verdadero "nulo".
el "??"- El operador detecta solo las referencias nulas, no los objetos que emulan el comportamiento "nulo".