Por que não posso usar '??' Operand for System.dbnull Valor?
Pergunta
Eu tenho uma tabela de dados Oracle buscando colunas nulas.Então, pensei em manter o código simples e agradável e usar o ??operando.AlternatePhoneNumber é uma string no meu modelo C#.
AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""
No entanto, mesmo com esse código ainda recebo o erro.
System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
Eu sei o que o erro significa, mas por que é ??não pode ser usado em DBNull?Nulo e DBNull não são essencialmente iguais?
Obrigado.
Solução
O ??
operador só se aplica a reais null
S.
null
e DBNull.Value
não são os mesmos; DBNull.Value
é simplesmente um objeto de espaço reservado.
Além disso, essa exceção vem de dentro do AlternatePhoneNumber
propriedade, antes de seu ??
operador executa.(Seu código não tem conversão).
Se customer
é uma linha em um conjunto de dados digitado, altere a coluna NullValue
propriedade no designer.
Outras dicas
null e DBNull não são iguais.System.DBNull é um objeto real.
O problema é que AlternatePhoneNumber
é uma sequência.DBNull não é.
Em vez disso, tente isto:
AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
Fazem isto:
public T IfNull<T>(object o, T value)
{
return (o == DbNull.Value) ? value : (T)o;
}
DBNull é um tipo com um único valor e não é o mesmo que uma referência de string nula, e é por isso que você não pode usar ??
.Você poderia fazer isso no entanto:
string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
Como outras respostas afirmam, null
significa uma referência que não se refere a nenhum objeto, enquanto DBNull
é uma classe fornecida pelo ADO.NET para indicar quando um campo ou valor é NULL no banco de dados (ou em um DataTable).
Embora você possa usar o operador condicional (ternário) (?:) para fazer o que quiser:
AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull
? ""
: customer.AlternatePhoneNumber;
Eu costumo encerrar isso em um método de extensão:
static class NullExtensions
{
public static T WhenNull<T>( this object value, T whenNullValue )
{
return (value == null || value is DBNull)
? whenNullValue
: (T)value;
}
}
o que acho que torna o código mais fácil de ler e entender.
AlternatePhoneNumber = customer.AlternatePhoneNumber.WhenNull( "" );
DBNull NÃO é um verdadeiro "nulo".
O "??" - O operador detecta apenas referências nulas, não objetos que imitam o comportamento "nulo".