3

I have an Oracle data table fetching columns that be null. So I figure to keep the code nice and simple that I'd use the ?? operand. AlternatePhoneNumber is a string in my C# model.

AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""

However, even with that code I still get the error.

System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.

I know what the error means but why is ?? not usable on DBNull? Isn't null and DBNull essentially the same?

Thank you.

Mike
  • 4,257
  • 3
  • 33
  • 47

7 Answers7

15

The ?? operator only applies to actual nulls.

null and DBNull.Value are not the same; DBNull.Value is simply a placeholder object.

Also, that exception is coming from inside the AlternatePhoneNumber property, before your ?? operator executes. (Your code doesn't have a cast).

If customer is a row in a typed dataset, change the column's NullValue property in the designer.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
3

null and DBNull are not the same. System.DBNull is an actual object.

Moose
  • 5,354
  • 3
  • 33
  • 46
3

The problem is that AlternatePhoneNumber is a string. DBNull is not.

Try this instead:

AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
Toby
  • 7,354
  • 3
  • 25
  • 26
2

DBNull is a type with a single value, and is not the same as a null string reference, which is why you can't use ??. You could do this however:

string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
Lee
  • 142,018
  • 20
  • 234
  • 287
  • 1
    This code is wrong on many levels. `DBNull` is miscapitalized. You shouldn't bother calling `.Equals`. `Customer` is neither`DBNull` nor a `string`. – SLaks Jul 09 '10 at 13:47
2

Do this:

public T IfNull<T>(object o, T value)
{
   return (o == DbNull.Value) ? value : (T)o;       
}
Andrey
  • 59,039
  • 12
  • 119
  • 163
1

As other replies state, null means a reference that refers to no object, while DBNull is a class supplied by ADO.NET to indicate when a field or value is NULL at the database (or in a DataTable).

While you can use the conditional (ternary) operator (?:) to do what you want:

AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull 
                           ? "" 
                           : customer.AlternatePhoneNumber;

I tend to wrap this up in an extension method:

static class NullExtensions
{
    public static T WhenNull<T>( this object value, T whenNullValue )
    {
        return (value == null || value is DBNull)
            ? whenNullValue
            : (T)value;
    }
}

which I find makes the code easier to read and understand.

AlternatePhoneNumber = customer.AlternatePhoneNumber.WhenNull( "" );
LBushkin
  • 129,300
  • 32
  • 216
  • 265
  • This won't compile. `AlternatePhoneNumber` is a string. – SLaks Jul 09 '10 at 13:59
  • @SLaks: Which part won't compile? The extension method accepts an `object` and returns a type that matches the default value. – LBushkin Jul 09 '10 at 14:10
  • `customer.AlternatePhoneNumber is DBNull` won't compile because it's statically typed as `string`. Your extension method won't help, because the exception is coming from inside the property. – SLaks Jul 09 '10 at 14:12
  • @SLaks: Ah, I see what you're saying. Ye, the OP needs to change the implementation of the property in that case. – LBushkin Jul 09 '10 at 14:38
1

DBNull is NOT a real "null".

The "??" - operator detects only null - references, not objects that emulate "null" behavior.

Turing Complete
  • 929
  • 2
  • 12
  • 19