C# ?? (零合并)vs?(三元if)表达式
请看下面的示例代码:C# ?? (零合并)vs?(三元if)表达式,c#,.net,C#,.net,请看下面的示例代码: short? myNullableShort = 5; short myShort = 0; // It works myShort = myNullableShort ?? 0; // It doesn't work, Compiler error // Cannot implicitly convert type 'short?' to 'short'. // An explicit conversion exists (are you missing a cas
short? myNullableShort = 5;
short myShort = 0;
// It works
myShort = myNullableShort ?? 0;
// It doesn't work, Compiler error
// Cannot implicitly convert type 'short?' to 'short'.
// An explicit conversion exists (are you missing a cast?)
myShort = myNullableShort != null ? myNullableShort : 0;
我能理解为什么第二个不起作用。但是,我希望第一个会导致编译器错误,但事实并非如此
我的问题是,为什么第一个很好用?当你到达终点时:
myShort = myNullableShort != null ? myNullableShort : 0;
myNullableShort仍然是可为null的,并且不能将可为null的转换为不可为null的
试试这个:
myShort = myNullableShort.HasValue ? myNullableShort.Value : 0;
第一种方法之所以有效,是因为您可以从一个不可为null的值中为一个可为null的值赋值,并且
myNullableShort??0
保证在到达以下行时返回myNullableShort
(如果存在)或0
的值:
myShort = myNullableShort != null ? myNullableShort : 0;
myNullableShort仍然是可为null的,并且不能将可为null的转换为不可为null的
试试这个:
myShort = myNullableShort.HasValue ? myNullableShort.Value : 0;
第一种方法之所以有效,是因为您可以从一个不可为null的值中为一个可为null的值赋值,并且
myNullableShort??0
保证返回myNullableShort
(如果存在)或0
myNullableShort??0的工作原理类似于myNullableShort!=无效的myNullableShort.值:0
。也就是说,?:
的中间操作数是short
类型的表达式,而不是short?
但是,如果您想避免使用?
,一种比使用更具可读性的书写方式:
是myNullableShort.GetValueOrDefault()
,或者是稍微详细一点的myNullableShort.GetValueOrDefault(0)
实际上,当您编写
myNullableShort时,编译器将在后台使用myNullableShort.GetValueOrDefault()
??0
:a??b
转换为a.HasValue?a、 GetValueOrDefault():b作为一种微优化。myNullableShort??0的工作原理类似于myNullableShort!=无效的myNullableShort.值:0
。也就是说,?:
的中间操作数是short
类型的表达式,而不是short?
但是,如果您想避免使用?
,一种比使用更具可读性的书写方式:
是myNullableShort.GetValueOrDefault()
,或者是稍微详细一点的myNullableShort.GetValueOrDefault(0)
实际上,当您编写
myNullableShort时,编译器将在后台使用myNullableShort.GetValueOrDefault()
??0
:a??b
转换为a.HasValue?a、 GetValuerDefault():b,作为一种微观优化。为什么会出现错误?期望值应该是规范所说的任何值。该规范还说,“默认”值会根据需要升级为可为空的版本。这是很明显的,因为a)手工操作会很麻烦,因为它是用三元组完成的;b)编译器可以很容易、毫不含糊地猜测您的意图。为什么您会期望出现错误?期望值应该是规范所说的任何值。该规范还说,“默认”值会根据需要升级为可为空的版本。这是很明显的,因为a)手动操作会很麻烦,因为它是用三元函数完成的;b)编译器可以轻松而明确地猜测您的意图。出于好奇,您知道它为什么使用GetValueOrDefault()
?在我看来,OrDefault
部分永远不会执行。我确实确认了它确实按照您所说的编译,但我仍然很好奇为什么它没有编译成a.HasValue?a、 值:b
而不是。@Robnull
类型(部分)被定义为大致public struct Nullable{private bool hasValue;private T Value;public bool hasValue{get{return hasValue;}}public T GetValueOrDefault(){return Value;}public T T Value{get{if(!hasValue)抛出新的invalidoOperationException();return value;}}}}
函数直接返回值
字段,值
属性添加了抛出异常的逻辑,因此避免在不需要的地方使用额外的逻辑,从而提高了速度。出于好奇,您知道它为什么使用GetValueOrDefault吗()
?在我看来,或default
部分永远不会执行。我确实确认它确实按照您所说的方式编译,但我仍然很好奇为什么它不编译为a.HasValue?a.Value:b
。@RobNullable
类型(部分)被定义为大致公共结构Nullable{private bool hasValue;private T value;public bool hasValue{get{return hasValue;}}}}public T GetValueOrDefault(){return value;}public T value{get{if(!hasValue)抛出新的invalidooperationexception();return value;}}}
TheGetValueOrDefault()
函数直接返回值
字段,值
属性添加了抛出异常的逻辑,因此避免了不需要的额外逻辑,从而提高了速度。