您的位置:知识库 » .NET技术

[你必须知道的.NET]第二十一回:认识全面的null

作者: Anytao  来源: 博客园  发布时间: 2008-10-13 11:05  阅读: 5849 次  推荐: 0   原文链接   [收藏]  

系列文章导航:

[你必须知道的.NET] 开篇有益

[你必须知道的.NET] 第一回:恩怨情仇:is和as

[你必须知道的.NET] 第二回:对抽象编程:接口和抽象类

[你必须知道的.NET] 第三回:历史纠葛:特性和属性

[你必须知道的.NET] 第四回:后来居上:class和struct

[你必须知道的.NET] 第五回:深入浅出关键字---把new说透

[你必须知道的.NET] 第六回:深入浅出关键字---base和this

[你必须知道的.NET] 第七回:品味类型---从通用类型系统开始

[你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理

[你必须知道的.NET] 第九回:品味类型---值类型与引用类型(中)-规则无边

[你必须知道的.NET] 第十回:品味类型---值类型与引用类型(下)-应用征途

[你必须知道的.NET] 第十一回:参数之惑---传递的艺术(上)

[你必须知道的.NET] 第十二回:参数之惑---传递的艺术(下)

[你必须知道的.NET] 第十三回:从Hello, world开始认识IL

[你必须知道的.NET] 第十四回:认识IL代码---从开始到现在

[你必须知道的.NET] 第十五回:继承本质论

[你必须知道的.NET] 第十六回:深入浅出关键字---using全接触

[你必须知道的.NET] 第十七回:貌合神离:覆写和重载

[你必须知道的.NET] 第十八回:对象创建始末(上)

[你必须知道的.NET] 第十九回:对象创建始末(下)

[你必须知道的.NET]第二十回:学习方法论

[你必须知道的.NET]第二十一回:认识全面的null

[你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考

[你必须知道的.NET]第三十二回,深入.NET 4.0之,Tuple一二


[你必须知道的.NET]第二十一回:认识全面的null

说在,开篇之前

null、nullable、??运算符、null object模式,这些闪亮的概念在你眼前晃动,我们有理由相信“存在即合理”,事实上,null不光合理,而且重要。本文,从null的基本认知开始,逐层了解可空类型、??运算符和null object模式,在循序之旅中了解不一样的null。

你必须知道的.NET,继续全新体验,分享更多色彩。

                                                                                                                       www.anytao.com

 

1 从什么是null开始?

null,一个值得尊敬的数据标识。

一般说来,null表示空类型,也就是表示什么都没有,但是“什么都没有”并不意味“什么都不是”。实际上,null是如此的重要,以致于在JavaScript中,Null类型就作为5种基本的原始类型之一,与Undefined、Boolean、Number和String并驾齐驱。这种重要性同样表现在.NET中,但是一定要澄清的是,null并不等同于0,"",string.Empty这些通常意义上的“零”值概念。相反,null具有实实在在的意义,这个意义就是用于标识变量引用的一种状态,这种状态表示没有引用任何对象实例,也就是表示“什么都没有”,既不是Object实例,也不是User实例,而是一个空引用而已。

在上述让我都拗口抓狂的表述中,其实中心思想就是澄清一个关于null意义的无力诉说,而在.NET中null又有什么实际的意义呢?

在.NET中,null表示一个对象引用是无效的。作为引用类型变量的默认值,null是针对指针(引用)而言的,它是引用类型变量的专属概念,表示一个引用类型变量声明但未初始化的状态,例如:

            object obj = null;

此时obj仅仅是一个保存在线程栈上的引用指针,不代表任何意义,obj未指向任何有效实例,而被默认初始化为null。

object obj和object obj = null的区别?

那么,object obj和object obj = null有实际的区别吗?答案是:有。主要体现在编译器的检查上。默认情况下,创建一个引用类型变量时,CLR即将其初始化为null,表示不指向任何有效实例,所以本质上二者表示了相同的意义,但是有有所区别:

            // Copyright   : www.anytao.com        
            // Author      : Anytao,http://www.anytao.com        
            // Release     : 2008/07/31 1.0
 
            //编译器检测错误:使用未赋值变量obj
            //object obj;
 
            //编译器理解为执行了初始化操作,所以不引发编译时错误
            object obj = null;
            
            if (obj == null)
            {
                //运行时抛出NullReferenceException异常
                Console.WriteLine(obj.ToString());
            }

:当我把这个问题抛给几个朋友时,对此的想法都未形成统一的共识,几位同志各有各的理解,也各有个的道理。当然,我也慎重的对此进行了一番探讨和分析,但是并未形成完全100%确定性的答案。不过,在理解上我更倾向于自己的分析和判断,所以在给出上述结论的基础上,也将这个小小的思考留给大家来探讨,好的思考和分析别忘了留给大家。事实上,将

        static void Main(string[] args)
        {
            object o;
            object obj = null;
        }

反编译为IL时,二者在IL层还是存在一定的差别:

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] object o,
        [1] object obj)
    L_0000: nop 
    L_0001: ldnull 
    L_0002: stloc.1 
    L_0003: ret 
}

前者没有发生任何附加操作;而后者通过ldnull指令推进一个空引用给evaluation stack,而stloc则将空引用保存。

回到规则

在.NET中,对null有如下的基本规则和应用:

  • null为引用类型变量的默认值,为引用类型的概念范畴。
  • null不等同于0,"",string.Empty。
  • 引用is或as模式对类型进行判断或转换时,需要做进一步的null判断。

 

快捷参考

                                                                                                                       www.anytao.com

  • 判断一个变量是否为null,可以应用==或!=操作符来完成。
  • 对任何值为nul的l变量操作,都会抛出NullReferenceException异常。

 

0
0
标签:.NET null

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻