zoukankan      html  css  js  c++  java
  • (完整版本)周一深说未将对象引用设置到对象的实例(System.NullReferenceException)

    注:不好意思,上次发的因事匆忙没给出完整实现.特重发补上.

    1. 异常:

            "未将对象引用设置到对象的实例"

    2. 本质

        1). 字符串的空引用.

        2). 空对象的空引用.

    3. 解决方案I:

          简单直白:在所有引用地方判断

           . if(!string.IsNullOrEmpty(User.UserName))

           .if(null!=User)

          点评:  面向过程开发的思维.

           A.这种办法看起来确实像一个很有经验的老鸟写的代码,不错,没有任何问题.但事实上只能称得上细心,与"菜"和"老"一点关系也没有. 就好像有人告诉你:这地方有雷,不能踩. 所有的人都会绕过去的,除非傻子.

          B. 看起来很稳定可靠,其实是最不可靠的:比如

              User类有N个字符串属性: UserName,NickName,Address...

              一个方法中都用到了则要:  if(!string.IsNullOrEmpty(User.UserName) && !string.IsNullOrEmpty(User.NickName).......)

             这是一个非常有看点的一行代码,别说人的精力有限,神仙也难保证在一个上十万行代码里面每个地方都判断,致命的一点是这个代码不是你一个写,你能保证每人都不是你认为的傻子吗?老板肯会花重金全部招聘老鸟?

           C. 最终的结果:   XXX代码规范.doc中的"每个引用前要判空的"的规范形同虚设,空引用的异常隔三叉五的跑出来,老板经常跳出来骂人.

          

     4. 解决方案II.

           先具备个基本素质:理解面向对象编程. 理解设计模式.

           底层保证不返回空串,而是返回空白串.

           底层保证不返回空对象,而是空白对象.

           最外层逻辑用Try Catch

          点评:

               A. 解决99%的空引用,除非你一定要用空引用异常来做为业务逻辑.

               B. 相当可靠,除非你故意给一个对象主动设置为NULL.

               C. 最外层一道Try Catch关,万无一失保证老板不会一个月之内出来骂你一次,最多只是偶尔来问下: "系统繁忙,稍后再试",是怎么回事?


    5. 详细代码实现:

        空引用无非两种常见类型:字符串的空,对象的空.

        1). 字符串:在面向对象的思想里面值变量根源是来自于对象属性的,就是通常说的实体类属性:

             User.cs

             private string _userName="";

             public string UserName

       {

                 get{ return _userName;}  //100%保证不会出现User.UserName==null的情况.

                 set{ if(null!=value) _userName=value;}

             }

         2).  实例: 在底层的DAO返回空白对象.

    UserDAO.cs

             /// <summary>

            /// 第一行,最后一行代码:在try catch之外独立,保证返回空白对象.

            /// 业务逻辑始终是用存在的对象的状态(比如这里是:user.ID的值)来指挥外层应用. 

            /// 绝不应该把user==null的这种状态作为外层应用的一个处理分支. 

            /// </summary>

            /// <param name="userID"></param>

            /// <returns></returns>

            public User Get(long userID)

            {

                User user=new User();  //第一行:初始化空白对象.

                try

                {

                    DataHelper hp=new DataHelper();

                    DbParameter[] pars=new DbParameter{ hp.CreateParameter("UserID",userID)};

                    IDataReader dr=hp.ExcuteDataReader(getSp,pars);

                    if(dr.Read())

                    {

                        user.ID=userID; //外层:user.ID==0表示没有取到数据;而不是用user==null来判断.

                        user.UserName=(string)dr["UserName"];

                    }

                }

                catch(Exception e)

                {

                    Log.Write("UserDAO.Get:"+e.Message);

                }

                return user;//最后一行:保证100%能返回空白对象.

            }

     

           3). 应用层次的最外层用try catch来保证程序的稳定性: 这一点不用代码说都明白.



      

  • 相关阅读:
    Java 动态编译
    在ubuntu 18.04下,无线网卡无驱动,连不上wifi,显示wifi没有适配器的解决方法
    由浅入深了解Thrift(1,2,3)
    Docker系列05:docker镜像制作 &Docker file
    Docker系列04:docker数据存储
    Docker系列03:docker网络
    关于在github上 下载源码 clone 非 master 分支的代码
    CentOS 6 & 7 忘记root密码的修改方法
    Windows RDP远程连接CentOS 7
    Windows 上用IntelliJ Idea调试百度大数据分析框架Apache Doris FE
  • 原文地址:https://www.cnblogs.com/kcitwm/p/2120862.html
Copyright © 2011-2022 走看看