Matt Phillips
Matt Phillips

Reputation: 11529

C# Ternary expression type conversion

Why is the compiler not able to automatically convert the values in this expression properly?

var input = "Hello";
object x = string.IsNullOrEmpty(input) ? input : DBNull.Value;

//could try this too and get similar compile time error
object x2 = string.IsNullOrEmpty(input) ? 1 : input;

I understand that DBNull.Value cannot be cast to a string; However, I'm curious as to why it cannot be coalesced into an object because the result is just storing a reference. If you place (object) in front of DBNull.Value it will compile and run just fine.

Upvotes: 1

Views: 1396

Answers (3)

gdoron
gdoron

Reputation: 150313

You can fix it with:

string x = string.IsNullOrEmpty(input) ?
                                       input :
                                       DBNull.Value.ToString();

I have found this excellent explanations in Eric Lippert's blog post on Type inference woes:

The specification for the ?: operator states the following:

The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,

  • If X and Y are the same type, then this is the type of the conditional expression.

  • Otherwise, if an implicit conversion exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.

  • Otherwise, if an implicit conversion exists from Y to X, but not from X to Y, then X is the type of the conditional expression.

  • Otherwise, no expression type can be determined, and a compile-time error occurs.

In this case:

  • string and DBNull aren't the same type.
  • string doesn't have an implicit conversion to DBNull
  • DBNull doesn't have an implicit conversion to string

So we end up with a compile-time error.

The compiler doesn't check what is the type that can "hold" those two types.

Upvotes: 2

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 62002

Help the compiler find the common base type you want, like this:

object x = string.IsNullOrEmpty(input) ? (object)input : DBNull.Value;

Upvotes: 2

Matthew
Matthew

Reputation: 25793

It is because string is not castable to DbNull and vice-versa. When using the ternary operator, both resultant operands must be compatible.

Upvotes: 3

Related Questions