为什么在三元运算符中赋值null失败:null和int之间没有隐式转换?
这失败了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);
有没有办法让三元运算符成功?
在确定右侧的类型时,编译器会忽略左侧。 所以当它试图推断出类型时
Int64.Parse(myOtherVar) == 0 ? null : Int64.Parse(myOtherVar)
它没有注意左手边long?
的事实long?
。 为了确定右侧的类型,它注意到了这一点
Int64.Parse(myOtherVar)
是一个long
,现在尝试查看null
是否可以隐式转换为long
。 由于它不能,您会收到您看到的错误消息。
从C#规范的第7.14节开始:
forms
b ? x : y
条件表达式b ? x : y
b ? x : y
….
?:
运算符的第二个和第三个操作数x
和y
控制条件表达式的类型。(1)如果
x
有X
型,y
有Y
型一个。 如果从
X
到Y
存在隐式转换(第6.1节),而不是从Y
到X
,则Y
是条件表达式的类型。湾 如果从
Y
到X
存在隐式转换(第6.1节),而不是从X
到Y
,则X
是条件表达式的类型。C。 否则,不能确定表达式类型,并发生编译时错误。
(2)如果
x
和y
只有一个具有类型,并且x
和y
都可以隐式转换为该类型,那么这就是条件表达式的类型。(3)否则,不能确定表达式类型,并发生编译时错误。
请注意,我们处于情境(2),其中x
为null
并且没有类型, y
是Int64.Parse(myOtherVar)
并且类型为long
。 请注意, x
不能隐式转换为y
的类型。 因此,(1)和(2)都失败了,我们导致(3)导致编译时错误激发了你的问题。 请注意上面的隐含结论,即左侧在确定右侧的类型时不起作用。
纠正这个替代
Int64.Parse(myOtherVar)
同
(long?)Int64.Parse(myOtherVar)
现在,之所以如此
myVar = null;
可以将myVar
声明为long?
是因为编译器知道存在从null
到long?
的隐式转换long?
。
最后,如果myOtherVar
无法解析为long
,则会抛出myOtherVar
。 请注意,您还要执行两次解析,这是不必要的。 更好的模式是
long value; if(Int64.TryParse(myOtherVar, out value)) { myVar = value == 0 ? null : (long?)value; } else { // handle case where myOtherVar couldn't be parsed }
由于三元运算符的最后部分,您的运算符用法返回Int64
而不是nullable
的Int64
。 如果您改为:
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;
我相信你的意思是说:
myVar = value == 0 ? null : (long?)value;
代替
myVar = value == 0 ? null : value;
我喜欢’out’变量的用法。 谢谢。
这将有效:
long? myVar = (long?)myOtherVar == 0 ? null : (long?)myOtherVar;
..对于那些喜欢简短答案的人。
编译器尝试从左到右评估表达式
long? myVar = Int64.Parse( myOtherVar) == 0 ? null : Int64.Parse( myOtherVar);
int64.parse
方法返回long
值而不是nullable
long值。 所以null
和Int64.Parse( myOtherVar);
之间没有转换Int64.Parse( myOtherVar);
所以,试试这个吧
long? myVar = Int64.Parse(myOtherVar) == 0 ? (long?) null : Int64.Parse(myOtherVar);
要么
long? myVar = Int64.Parse(myOtherVar) == 0 ? null : (long?) Int64.Parse(myOtherVar);