C#的新手,所以我遇到了一个简短陈述的问题。我想转换......
if (m_dtLastLogin == null)
drow["LastLogin"] = DBNull.Value;
else
drow["LastLogin"] = m_dtLastLogin;
到
drow["LastLogin"] = (m_dtLastLogin == null) ? System.DBNull.Value : m_dtLastLogin;
长版本工作得很好,但是,简写版本会生成错误“无法确定条件类型,因为'System.DBNull'和'System.DateTime?'之间没有隐式转换。”我的支持代码基本上就是......
private DateTime? m_dtLastLogin;
m_dtLastLogin = null;
DataRow drow;
drow = m_oDS.Tables["Users"].Rows[0];
有人可以用这个简短的手帮助我吗?
答案 0 :(得分:5)
嗯,错误信息很清楚。编译器需要确定整个x?y:z表达式的类型。如果y和z具有相同的类型,则很容易。如果y可转换为z,则表达式的类型为z的类型,同样,如果z可转换为y,则类型为y的类型。
在你的情况下,y的类型是DBNull,y的类型是m_dtLastLogin的类型(可能是日期时间)。这两种类型不能相互转换,并且没有公共基类型(Object除外),因此编译器不知道该怎么做。
但是,您可以通过将y或z强制转换为object:
来帮助编译器drow["LastLogin"] = (m_dtLastLogin == null) ? (object)System.DBNull.Value : m_dtLastLogin;
或
drow["LastLogin"] = (m_dtLastLogin == null) ? System.DBNull.Value : (object)m_dtLastLogin;
这样整个表达式就有了type对象,然后可以将其赋值给drow["LastLogin"]
。
参考: C#语言规范 - http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf
第14.13节,条件算子
引用
?:运算符的第二个和第三个操作数控制条件表达式的类型。设X和Y是第二个和第三个操作数的类型。然后,
如果X和Y的类型相同,那么这就是条件表达式的类型。
否则,如果从X到Y存在隐式转换(第13.1节),而不是从Y到X,则Y是条件表达式的类型。
否则,如果从Y到X存在隐式转换(第13.1节),而不是从X到Y,则X是条件表达式的类型。
否则,无法确定表达式类型,并发生编译时错误。
答案 1 :(得分:0)
将两者都投射到“对象”:
drow["LastLogin"] = (m_dtLastLogin == null) ? (object)System.DBNull.Value :
(object)m_dtLastLogin;
条件运算符要求两个部分(“then”和“else”部分)求值为相同的类型,这将是表达式的结果类型。
您的原始版本在没有强制转换的情况下工作,因为它最终位于object
类型的字段中。