为什么在三元运算符中赋值null失败:null和int之间没有隐式转换?

时间:2010-11-27 05:02:09

标签: c# ternary-operator

此操作因There is no implicit conversion between 'null' and 'int'

而失败
long? myVar = Int64.Parse( myOtherVar) == 0 ? null : Int64.Parse( myOtherVar);

然而,这成功了:

if( Int64.Parse( myOtherVar) == 0)
    myVar = null;
else
    myVar = Int64.Parse( myOtherVar);

有没有办法让三元运算符成功?

5 个答案:

答案 0 :(得分:25)

在确定右侧的类型时,编译器会忽略左侧。所以当它试图推断出

的类型时
Int64.Parse(myOtherVar) == 0 ? null : Int64.Parse(myOtherVar)

它没有注意到左侧是long?的事实。为了确定右侧的类型,它注意到

Int64.Parse(myOtherVar)

long,现在尝试查看null是否可以隐式转换为long。由于它不能,您会收到您看到的错误消息。

来自C#规范的§7.14:

  

b ? x : y ....

形式的条件表达式      

x运算符的第二个和第三个操作数y?:控制条件表达式的类型。

     

(1)如果x的类型为Xy的类型为Y,那么

     

一个。如果从XY存在隐式转换(第6.1节),而不是YX,那么Y是条件表达式的类型

     

湾如果从YX存在隐式转换(第6.1节),而不是XY,那么X是条件表达式的类型

     

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

     

(2)如果xy中只有一个具有类型,并且xy都可以明确转换为该类型,那么这就是条件表达式的类型。

     

(3)否则,不能确定表达式类型,并发生编译时错误。

请注意,我们处于情况(2),其中xnull且没有类型且yInt64.Parse(myOtherVar)并且类型为long 。请注意,x不能隐式转换为y类型。因此,(1)和(2)都失败了,我们导致(3)导致编译时错误激发了你的问题。 请注意上述隐含的结论,左手边在确定右手边的类型方面没有作用。

要纠正此替换

Int64.Parse(myOtherVar)

(long?)Int64.Parse(myOtherVar)

现在,之所以

myVar = null;

可以将myVar声明为long?,因为编译器知道存在从nulllong?的隐式转换。

最后,如果Int64.Parse无法解析为myOtherVarlong将会抛出。请注意,您还要执行两次解析,这是不必要的。更好的模式是

long value;
if(Int64.TryParse(myOtherVar, out value)) {
    myVar = value == 0 ? null : (long?)value;
}
else {
    // handle case where myOtherVar couldn't be parsed
}

答案 1 :(得分:2)

由于三元运算符的最后一部分,您的运算符用法返回Int64而不是nullable。如果您这样做可能会有效:

long? myVar = Int64.Parse( myOtherVar) == 0 ? null :
   (long?)Int64.Parse( myOtherVar);

这样您就会返回long?,因此null不需要转换为Int64

此外,您在代码中将值转换两次,不必要(一次测试,一次获取值)。因此,您的代码可能更好:

long? tempVar = Int64.Parse(myOtherVar);
long? myVar = tempVar==0? null : tempVar;

答案 2 :(得分:2)

我相信你的意思是说:

  myVar = value == 0 ? null : (long?)value;

而不是

  myVar = value == 0 ? null : value;

我喜欢使用'out'变量。 感谢。

答案 3 :(得分:0)

这将有效:

long? myVar = (long?)myOtherVar == 0 ? null : (long?)myOtherVar;

..对于那些喜欢简短答案的人。

答案 4 :(得分:0)

编译器尝试从左到右评估表达式

long? myVar = Int64.Parse( myOtherVar) == 0 ? null : Int64.Parse( myOtherVar);

int64.parse方法返回long值而不是nullable长值。所以nullInt64.Parse( myOtherVar);之间没有转化 所以,试试这个

long? myVar = Int64.Parse(myOtherVar) == 0 ? (long?) null : Int64.Parse(myOtherVar);

OR
long? myVar = Int64.Parse(myOtherVar) == 0 ? null : (long?) Int64.Parse(myOtherVar);