当前位置:  开发笔记 > 编程语言 > 正文

为什么这个代码在C#中无效?

如何解决《为什么这个代码在C#中无效?》经验,为你挑选了3个好方法。

以下代码将无法编译:

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):删除了"autoboxing"标签,因为这个问题没有涉及拳击.



1> Jon Skeet..:

编译器要求第二个和第三个操作数的类型相同,或者一个操作数可以隐式转换为另一个操作数.在您的情况下,类型是DBNull和字符串,它们都不能隐式转换为另一个.将它们中的任何一个转换为对象解决了这个问题.

编辑:看起来它在Java中确实合法.当谈到方法重载时,它是如何工作的,我不确定......我刚刚看了JLS,当有两个不兼容的引用时,条件的类型是什么的非常不清楚涉及的类型.C#的工作方式偶尔可能会更加刺激,但IMO更清晰.

C#3.0规范的相关部分是7.13,条件运算符:

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

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

否则,如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型.

否则,如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型.

否则,无法确定表达式类型,并发生编译时错误.



2> Keith..:

DBNull.Value返回类型DBNull.

你想要的类型string.

虽然string可以null不是一个DBNull.

在您的代码中,equals右侧的语句在赋值给对象之前执行.

基本上如果您使用:

[condition] ? true value : false value;

在.Net中,无论你将它们分配给它们,都需要将true和false选项隐式转换为相同的类型.

这是C#处理类型安全的结果.例如,以下内容有效:

string item = "item";

var test = item != null ? item : "BLANK";

C#3不支持动态类型,那么什么是测试?在C#中,每个赋值也是一个带有返回值的语句,因此虽然var构造在C#3中是新的,但是equals右边的语句总是必须解析为单个类型.

在C#4及更高版本中,您可以明确支持动态类型,但我认为这不会有帮助.



3> Konrad Rudol..:

顺便说一句,您的代码是一个特殊情况,根本不必使用条件运算符.相反,null coalesce运算符更合适(但仍需要转换):

object result = (object)foo ?? DBNull.Value;

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有