2011-12-05 49 views
1

它是如何访问null可为空的索引HasValue
我看着编译的代码,它不是一个语法糖。'。'运算符为空可空

为什么这不会引发的NullReferenceException:

int? x = null; 
if (x.HasValue) 
{...} 

回答

11

这是因为int?是短期的Nullable<int>这是值类型,不是引用类型 - 所以你永远不会得到NullReferenceException

Nullable<T>结构看起来是这样的:

public struct Nullable<T> where T : struct 
{ 
    private readonly T value; 
    private readonly bool hasValue; 
    //.. 
} 

当分配null有编译器一些魔术的支持发生(它知道Nullable<T>和对待他们特别以这种方式),这只是设置hasValue字段在此实例中为false - 然后由HasValue属性返回。

+0

此外,struct从未分配null。 –

1

Like BrokenGlass说,一个int?实际上是一个Nullable<T>

结构总是包含一个值。通常你不能将一个结构变量设置为null,但在这种特殊情况下,你可以将它设置为default(Nullable<T>)。这将其内容设置为空而不是变量本身。

当您设置一个Nullable<T>的值,它使用一个隐含的操作者设置Value = value新值和HasValue = true

当您将Nullable<T>设置为空时,它会将所有结构的字段设为空。对于bool字段,如HasValue,null == false

由于Nullable<T>变量是一个结构,变量总是可以被引用,因为它的内容是空的而不是变量本身。

在MSDN页面struct的备注部分有关于结构的更多信息。

+1

“将结构变量设置为null将其内容设置为null,而不是变量本身。”这是错误的 - 您不能将null赋值给值类型/结构 - 除了'Nullable '外,编译器将会适当地将其转换为将'hasValue'字段设置为false。这是唯一可能的,因为编译器知道'Nullable ',因此是“魔术”评论。 – BrokenGlass

+0

@BrokenGlass,你说得对。我习惯VB.Net,目前在教自己的C#。在VB中,你可以指定'Dim x As SomeStructure = Nothing'。我猜这与'SomeStructure x = default(SomeStructure)',而不是'SomeStructure x = null'是一样的。 –

+0

@ Hand-E-Food,那么为什么不更新你的答案到C#(+ VB)? – gdoron