Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#三值表达式类型转换_C#_Ternary Operator_Compile Time - Fatal编程技术网

C#三值表达式类型转换

C#三值表达式类型转换,c#,ternary-operator,compile-time,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不能转换为字符串;然而,我很好奇为

为什么编译器不能正确地自动转换此表达式中的值

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前面,它将正常编译和运行

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

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

使用以下方法修复它:

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
因此,我们最终会出现编译时错误

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

用以下方法修复它:

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
因此,我们最终会出现编译时错误


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

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

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

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

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

我会用“需要从一种类型到另一种类型的隐式转换”来总结它。@gdoron也没有显式转换。我已经得到了那个部分。我想知道的是,为什么编译器不可能(可行)查看分配给(object)的类型并意识到这两种类型都有到object的隐式转换。忘掉他们之间的关系。@MattPhillips:这不是语言的工作方式。即使这里看起来很简单,也可以考虑调用过载方法的其他情况,其中可能存在各种可能的转换。如果每个表达式都有自己的类型,并且完全独立于它的使用方式进行标识,则会简单得多。有一些例外,例如lambda表达式和空文本,但它们增加了语言规则的复杂性-因此这些情况被保持在最低限度。我将其总结为“需要从一种类型到另一种类型的隐式转换”。@gdoron也没有显式转换。我已经得到了这一部分。我想知道的是,为什么编译器不可能(可行)查看分配给(object)的类型并意识到这两种类型都有到object的隐式转换。忘掉他们之间的关系。@MattPhillips:这不是语言的工作方式。即使这里看起来很简单,也可以考虑调用过载方法的其他情况,其中可能存在各种可能的转换。如果每个表达式都有自己的类型,并且完全独立于它的使用方式进行标识,则会简单得多。有一些例外,比如lambda表达式和空文本,但是它们增加了语言规则的复杂性-所以这些情况被保持在最低限度。这是有意义的。我想我要找的是
隐式的
部分。有点让你想知道为什么它不尝试对他们分配给的变量类型进行隐式转换。如果我存储到对象,我不在乎实际的类型是什么,因为我只是存储对它的引用。@mattfillips。然后你找到了……:)这是有道理的。我想我要找的是
隐式的
部分。有点让你想知道为什么它不尝试对他们分配给的变量类型进行隐式转换。如果我存储到对象,我不关心实际的类型是什么,因为我只是存储对它的引用