单行if语句生成强制转换错误

时间:2012-03-04 16:33:17

标签: c# if-statement

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];

有人可以用这个简短的手帮助我吗?

2 个答案:

答案 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类型的字段中。