5
var dict = new Dictionary<string, object>();
DateTime? myDate;

/*Next line gives: Type of conditional expression cannot be 
determined because there is no implicit conversion between 'System.DateTime?' 
and 'System.DBNull' */

dict.Add("breakit", myDate.HasValue ? myDate.Value : DBNull.Value);

I don't understand why there needs to be an implicit conversion if one or the other is going into a dictionary expecting type Object.

scottm
  • 27,829
  • 22
  • 107
  • 159
  • 2
    This is an extremely frequently asked question on SO. See http://stackoverflow.com/questions/2215745/conditional-operator-cannot-cast-implicitly/2215959#2215959 for details. See also my related article http://blogs.msdn.com/b/ericlippert/archive/2010/05/27/cast-operators-do-not-obey-the-distributive-law.aspx – Eric Lippert Jun 28 '11 at 14:24
  • 1
    You're welcome. The problem is that you are reasoning in the opposite direction that the compiler reasons. You are saying "I know that this is going to something that expects object". But the compiler doesn't know that you *a priori* desire the "object" method to be chosen. The compiler is trying to reason the other way. It is asking "is the method that expects object compatible with this expression?" To know that it must ask "What is the type of the expression?" **The problem is that it cannot work out the type of the expression in order to decide whether the expression works.** – Eric Lippert Jun 28 '11 at 15:27

2 Answers2

6

In C#, every conditional expression must have a type. What type is your expression of?

I understand your concern, the conversion is not needed for your particular case, but this is how C# compiler works, so you have to obey its rules.

This should work instead (I didn't check though):

dict.Add("breakit", myDate.HasValue ? (object)myDate.Value : (object)DBNull.Value);
Zruty
  • 8,377
  • 1
  • 25
  • 31
  • my expression should be of either type System.DateTime or DBNull depending on the condition of myDate.Value – scottm Jun 28 '11 at 14:10
  • then it's not a static type, but a dynamic type. C# compiler is static-typed (apart from some `dynamic` mechanics I'm not fully sure about). – Zruty Jun 28 '11 at 14:13
  • 7
    It is actually not true that *every* expression must have a type, but it is true that every *conditional expression* must have a type. There are four expressions in C# that have no type. The null literal, a lambda, an anonymous method, and a method group. In each case, the type information flows *from the context to the expression* rather than from the expression outwards, as it normally does. – Eric Lippert Jun 28 '11 at 14:22
1

Did you try:

DateTime? date = myDate.HasValue ? myDate.Value : null;

dict.Add("breakit", date);
Ken D
  • 5,880
  • 2
  • 36
  • 58
  • Even though, I don't understand why do we need to cast to object when it is the master base class! – Ken D Jun 28 '11 at 14:18