myNullableLong.HasValue和myNullableLong != null之间有什么区别吗?

44

当我有一个可空的long类型时,例如,以下两种写法有什么不同:

myNullableLong.HasValue 
并且
myNullableLong != null

这是真正的异步代码执行,还是只是“语法糖”?


请参考这个类似的问题 - DOK
这只涉及可读性。 - Mariusz Jamro
3个回答

59

这只是语法糖。它们的行为完全相同-空值测试实际上被编译成对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

你认为哪一个更加整洁? - Neil Knight
2
@Neil:这取决于上下文。我可能通常会使用空值比较,但偶尔我想HasValue更易读一些。 - Jon Skeet
2
谢谢。我必须说,我看到的!= nullHasValue比较多。 - Neil Knight
正如我所猜测的那样。这个问题是在代码审查中要求我将!= null更改为HasValue时出现的,我当时在质疑为什么... - Fiona - myaccessible.website
我知道这个问题有点老了,但是还是想知道答案。我个人更喜欢使用!= null。不过根据Jon的回答,如果在任何情况下!= null被编译为对HasValue的调用,那么使用HasValue可能更合理。不过编译器已经足够快了,所以这基本上是一个主观选择。我个人会坚持使用!= null :) - jamiebarrow
1
我想知道在Linq-To-Entities中是否也适用这个规则。我可以理解当与null进行显式比较时,它们是相等的,但是如果像这样比较两个可空字段会怎么样呢:Where( x => true && (x.t1.NullableField == x.t2.NullableField))。在TSQL中,如果两个字段都为null,则此类比较将失败,除非它显式注入一个“或者两个都为null”的检查。 - Triynko

8

这是一种语法糖; 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

3

编号。

C#编译器内置支持Nullable<T>,并将涉及null的等式操作转换为对结构体成员的调用。

n != nulln.HasValue都将编译为相同的IL代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接