我很好奇以下代码的工作原理(在VS调试器下运行):
int? x = null;
null
x.HasValue
false
如果x
确实为空,那么HasValue
指的是什么实例? HasValue
是作为扩展方法实现的,还是编译器特殊情况下使它神奇地起作用?
答案 0 :(得分:9)
因为x
不是引用类型。 ?
只是Nullable<T>
的语法糖,是struct
(值类型)。
答案 1 :(得分:5)
int?
实际上是一个结构Nullable<int>
。因此,您的x
不能为空,因为它始终是结构的实例。
答案 2 :(得分:4)
挥手答案:可空的结构是神奇的。
更长的答案:Null实际上并不是值所代表的。当你为一个可以为空的结构赋值null时,你将会看到在幕后发生的事情是不同的。
int? val = null; // what you wrote
Nullable<Int32> val = new Nullable<Int32>(); // what is actually there
在这种情况下,会创建一个结构实例,其T Value
设置为默认值,bool HasValue
属性设置为false。
您实际从Nullable<T>
获取空引用的唯一时间是装箱时,Nullable<T>
框直接发送到T
或null ,取决于是否设置了值。
答案 3 :(得分:2)
null
有几种含义。
编程语言中的一种以基于指针的方式呈现变量和内存(包括C#的引用虽然它隐藏了一些细节)是#34;这并不指向任何东西&#34 34。
另一个是&#34;这没有任何有意义的价值&#34;。
对于引用类型,我们经常使用前者来表示后者。我们可能会使用string label = null
表示&#34;没有有意义的标签。尽管如此,它仍然 仍然是关于内存中的内容和指向它的内容的问题。不过,它非常有用,在C#1.1中使用int
和DateTime
我们无法做到这一点真是太遗憾了
这是Nullable<T>
提供的内容,一种表达方式&#34;没有意义的价值&#34;,但在低于它null
的水平下方式null
字符串是(除非装箱)。它已经被赋值为null并且等于null,因此根据其他一些语义,它在逻辑上为null和null,但在&#34;它没有指向null什么&#34;参考和值类型之间的实现差异。
它只是&#34;没有指向任何东西&#34; reference-type null的一个方面,它阻止你调用实例方法。
实际上,即使这并非严格要求。 IL允许您在空引用上调用实例方法,只要它不与任何字段进行交互,它就可以工作。如果它(直接或间接)需要(直接或间接)那些字段,它就无法工作,因为它们不存在于空引用中,但如果该方法被定义为:{/ p>,它可以调用null.FineWithNull()
int FineWithNull()
{
//note that we don't actually do anything relating to the state of this object.
return 43;
}
使用C#决定不允许这样做,但它不是所有.NET的规则(我认为F#允许它,但我不确定,我知道非托管C ++允许它,它是在一些极少数情况下很有用。)
答案 4 :(得分:1)
使用int? x = null
时,会为x
分配一个Nullable<int>
的新实例,并将ist值设置为null
。
我不完全了解内部结构,但我认为赋值运算符本身有些过载。
答案 5 :(得分:1)
可空类型实际上不是null
,因为它仍然无法解决值类型不能为null
这一事实。相反,它是对Nullable<>
结构的引用(它也是一种值类型,不能是null
)。
更多信息here。
基本上,当您使用可空类型时,您总是指某个实例。该引用返回的默认信息是存储值(如果没有存储值,则为null
。)
答案 6 :(得分:1)
Nullable不是真正引用类型,它的实例方法是显示它的地方之一。从根本上说,它是一个结构类型,包含一个布尔标志和一个可以为空的类型的值。语言特殊情况各种运算符[要提升,或考虑(bool?)在某些情况下为null]和null文字,以及运行时特殊情况装箱,但除此之外它只是一个结构。
答案 7 :(得分:1)
这是一种全新的类型。 Nullable 不 T。
你所拥有的是类通用类:
public struct Nullable<T>
{
public bool HasValue { get { return Value != null; } }
public T Value { get; set; }
}
我确信它还有更多内容(特别是在吸气剂和制定者中,但简而言之就是这样。
答案 8 :(得分:0)
可空类型(在本例中为:nullable int)具有HasValue属性,它是boolean。如果HasValue为True,则Value属性(类型T,在本例中为int)将具有有效值。