当我有一个可空的long类型时,例如,以下两种写法有什么不同:
myNullableLong.HasValue
并且myNullableLong != null
这是真正的异步代码执行,还是只是“语法糖”?
这只是语法糖。它们的行为完全相同-空值测试实际上被编译成对HasValue
的调用。
示例:
public class Test
{
static void Main()
{
int? x = 0;
bool y = x.HasValue;
bool z = x != null;
}
}
IL:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 25 (0x19)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
IL_0000: ldloca.s V_0
IL_0002: ldc.i4.0
IL_0003: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0008: ldloca.s V_0
IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000f: pop
IL_0010: ldloca.s V_0
IL_0012: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0017: pop
IL_0018: ret
} // end of method Test::Main
HasValue
更易读一些。 - Jon Skeet!= null
比HasValue
比较多。 - Neil Knight!= null
。不过根据Jon的回答,如果在任何情况下!= null
被编译为对HasValue
的调用,那么使用HasValue
可能更合理。不过编译器已经足够快了,所以这基本上是一个主观选择。我个人会坚持使用!= null
:) - jamiebarrowWhere( x => true && (x.t1.NullableField == x.t2.NullableField))
。在TSQL中,如果两个字段都为null,则此类比较将失败,除非它显式注入一个“或者两个都为null”的检查。 - Triynko这是一种语法糖; Nullable<T>
实际上是一个 struct
,所以它不能实际上为 null
; 编译器会将与 null
比较的调用(例如您的第二个示例)转换为对 HasValue
的调用。
请注意,将 Nullable<T>
装箱为 object
将导致要么是 T
的值(如果它有一个值),要么是 null
(如果它没有值)。
即:
int? foo = 10; // Nullable<int> with a value of 10 and HasValue = true
int? bar = null; // Nullable<int> with a value of 0 and HasValue = false
object fooObj = foo; // boxes the int 10
object barObj = bar; // boxes null
Console.WriteLine(fooObj.GetType()) // System.Int32
Console.WriteLine(barObj.GetType()) // NullReferenceException
编号。
C#编译器内置支持Nullable<T>
,并将涉及null
的等式操作转换为对结构体成员的调用。
n != null
和n.HasValue
都将编译为相同的IL代码。