1

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

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 前面,它将编译并运行得很好。

4

3 回答 3

3

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

于 2012-05-14T20:58:35.887 回答
2

修复它:

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

我在Eric Lippert 博客中找到了这个极好的解释:

运营商的规范?:规定如下:

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

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

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

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

  • 否则,无法确定表达式类型,并出现编译时错误。

在这种情况下:

  • string并且DBNull不是同一类型。
  • string没有隐式转换为DBNull
  • DBNull没有隐式转换为string

所以我们最终会出现编译时错误。

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

于 2012-05-14T20:59:17.230 回答
2

帮助编译器找到你想要的通用基类型,像这样:

object x = string.IsNullOrEmpty(input) ? (object)input : DBNull.Value;
于 2012-05-14T21:02:16.687 回答