Ioa*_*nis 41 .net c# conditional-operator c#-2.0
我有这个C#2.0源代码的摘录:
object valueFromDatabase;
decimal result;
valueFromDatabase = DBNull.Value;
result = (decimal)(valueFromDatabase != DBNull.Value ? valueFromDatabase : 0);
result = (valueFromDatabase != DBNull.Value ? (decimal)valueFromDatabase : (decimal)0);
Run Code Online (Sandbox Code Playgroud)
第一个结果评估抛出,InvalidCastException而第二个结果评估不抛出.这两者有什么区别?
Eri*_*ert 101
更新:这个问题是我的博客2010年5月27日的主题.谢谢你这个好问题!
这里有很多令人困惑的答案.让我试着准确回答你的问题.让我们简化一下:
object value = whatever;
bool condition = something;
decimal result = (decimal)(condition ? value : 0);
Run Code Online (Sandbox Code Playgroud)
编译器如何解释最后一行?编译器面临的问题是条件表达式的类型必须对两个分支都是一致的.语言规则不允许您在一个分支上返回对象而在另一个分支上返回int.选择是object和int.每个int都可以转换为object,但并非每个对象都可以转换为int,因此编译器会选择对象.因此这是一样的
decimal result = (decimal)(condition ? (object)value : (object)0);
Run Code Online (Sandbox Code Playgroud)
因此返回的零是一个盒装的int.
然后将int解包为十进制.将盒装int解包为十进制是非法的.出于这个原因,请参阅我关于该主题的博客文章:
基本上,你的问题是你的行为就好像分配到十进制的转换一样,如下所示:
decimal result = condition ? (decimal)value : (decimal)0;
Run Code Online (Sandbox Code Playgroud)
但正如我们所见,那不是什么
decimal result = (decimal)(condition ? value : 0);
Run Code Online (Sandbox Code Playgroud)
手段.这意味着"将两个替代品都放入对象然后取消生成对象".
Guf*_*ffa 12
不同的是,编译器不能确定是之间的良好匹配一个数据类型Object和Int32.
您可以显式地将int值转换object为在第二个和第三个操作数中获取相同的数据类型以便它进行编译,但是couse意味着您正在装箱并取消装箱值:
result = (decimal)(valueFromDatabase != DBNull.value ? valueFromDatabase : (object)0);
Run Code Online (Sandbox Code Playgroud)
那将编译,但不会运行.您必须将十进制值设置为unbox作为十进制值:
result = (decimal)(valueFromDatabase != DBNull.value ? valueFromDatabase : (object)0M);
Run Code Online (Sandbox Code Playgroud)
运算符的类型将是对象,如果结果必须为0,则将隐式装箱.但是默认情况下0 literal是int类型所以你选择int.但是如果使用显式强制转换为十进制,则尝试将其取消包装,这是不允许的(盒装类型必须与您回放的那个相同).这就是为什么你可以得到例外.
以下是C#规范的摘录:
?:运算符的第二个和第三个操作数控制条件表达式的类型.设X和Y是第二个和第三个操作数的类型.然后,
| 归档时间: |
|
| 查看次数: |
16657 次 |
| 最近记录: |