【发布时间】:2010-09-17 03:59:50
【问题描述】:
以下代码将无法编译:
string foo = "bar";
Object o = foo == null ? DBNull.Value : foo;
我得到:错误 1 无法确定条件表达式的类型,因为 'System.DBNull' 和 'string' 之间没有隐式转换
要解决这个问题,我必须这样做:
string foo = "bar";
Object o = foo == null ? DBNull.Value : (Object)foo;
这个演员表似乎毫无意义,因为这当然是合法的:
string foo = "bar";
Object o = foo == null ? "gork" : foo;
在我看来,当三元分支是不同类型时,编译器不会将值自动装箱到类型对象...但是当它们是相同类型时,自动装箱是自动的。
在我看来,第一个声明应该是合法的......
谁能描述为什么编译器不允许这样做以及为什么 C# 的设计者选择这样做?我相信这在 Java 中是合法的......虽然我还没有验证这一点。
谢谢。
编辑:我想了解为什么 Java 和 C# 处理这个问题的方式不同,C# 中的幕后情况是什么使这个无效。我知道如何使用三元,并且不是在寻找一种“更好的方式”来编写示例。我了解 C# 中的三进制规则,但我想知道为什么...
编辑(Jon Skeet):删除了“自动装箱”标签,因为此问题不涉及装箱。
【问题讨论】:
-
如果像这里这样使用更有效的测试 DBNulls 的方法会更容易调试吗? :stackoverflow.com/questions/26809/…
-
其他答案解释得很好。一个额外的花絮:即使编译成功,这里也不会涉及拳击。 String 和 DBNull 都是引用(类)类型,而不是值类型,因此字符串可以存储在对象变量中而无需装箱。
-
问题添加到C# Tag Wiki
-
srsl,为什么有人没有想到 "int? = (xxx)? null : int; variant?? 我的意思是这是一个实际和常见的问题,那我为什么要这么做写 ...(int?)null : int; 这太疯狂了!
标签: c# nullable conditional-operator dbnull