C#三元表达式转换

时间:2012-05-14 20:57:22

标签: c# ternary-operator compile-time

为什么编译器无法正确自动转换此表达式中的值?

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;

我知道DBNull.Value不能转换为字符串;但是,我很好奇为什么它不能合并到一个对象,因为结果只是存储一个引用。如果将(object)放在DBNull.Value前面,它将编译并运行正常。

3 个答案:

答案 0 :(得分:3)

这是因为string不能投放到DbNull,反之亦然。使用三元运算符时,两个结果操作数必须兼容。

答案 1 :(得分:2)

修复:

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

我在 Eric Lippert blog中找到了这个出色的解释:

?:运算符的规范说明如下:

  

?:运算符的第二个和第三个操作数控制的类型   条件表达式。设X和Y为第二个和第二个的类型   第三个操作数。然后,

     
      
  • 如果X和Y是相同的类型,那么这是条件的类型   表达。

  •   
  • 否则,如果从X到Y存在隐式转换,   但不是从Y到X,那么Y是条件表达式的类型。

  •   
  • 否则,如果存在从Y到X的隐式转换,而不是来自   X到Y,则X是条件表达式的类型。

  •   
  • 否则,   没有表达式类型可以确定,并且发生编译时错误。

  •   

在这种情况下:

  • stringDBNull的类型不同。
  • string没有隐式转换为DBNull
  • DBNull没有隐式转换为string

所以我们最终会遇到编译错误。

编译器不会检查可以“保留”这两种类型的类型。

答案 2 :(得分:2)

帮助编译器找到所需的公共基类型,如下所示:

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