Reputation: 411
new to C# so I'm having an issue with a short-hand statement. I want to convert...
if (m_dtLastLogin == null)
drow["LastLogin"] = DBNull.Value;
else
drow["LastLogin"] = m_dtLastLogin;
to
drow["LastLogin"] = (m_dtLastLogin == null) ? System.DBNull.Value : m_dtLastLogin;
The long-hand version works great, however, the short-hand version generates the error "Type of conditional cannot be determined because there is no implicit conversion between 'System.DBNull' and 'System.DateTime?'". My supporting code is basically...
private DateTime? m_dtLastLogin;
m_dtLastLogin = null;
DataRow drow;
drow = m_oDS.Tables["Users"].Rows[0];
Can someone help me with the short-hand here?
Upvotes: 0
Views: 2061
Reputation: 8408
Well, the error message is pretty clear. The compiler needs to determine the type of the whole x?y:z expression. If y and z have the same type, it's easy. If y is convertible to z, the type of the expression is that of z, likewise if z is convertible to y the type is that of y.
In your case the type of y is DBNull, the type of y is the type of m_dtLastLogin (probably a datetime). Those two types cannot be converted into each other and have no common base type (except for Object), so the compiler doesn't know what to do.
You can help the compiler, however, by casting either y or z to object:
drow["LastLogin"] = (m_dtLastLogin == null) ? (object)System.DBNull.Value : m_dtLastLogin;
or
drow["LastLogin"] = (m_dtLastLogin == null) ? System.DBNull.Value : (object)m_dtLastLogin;
This way the whole expression has the type object, which can then be assigned to drow["LastLogin"]
.
Reference: C# language specification - http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf
Section 14.13, Conditional operator
Quote
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 (§13.1) 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 (§13.1) 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.
Upvotes: 5
Reputation: 39274
Cast both to "object":
drow["LastLogin"] = (m_dtLastLogin == null) ? (object)System.DBNull.Value :
(object)m_dtLastLogin;
The conditional operator requires that both parts (the "then" and "else" part) evaluate to the same type, which will be the result type of the expression.
Your original version worked without casts, because it ended up in a field of type object
.
Upvotes: 0