`
tubaluer
  • 浏览: 1448086 次
文章分类
社区版块
存档分类
最新评论
  • sblig: c / c++ 是不一样的都会输出 100
    j = j++

.net中的NULL

 
阅读更多

从我们刚学.Net编程起,我们的程序不断被从天而降NullReferenceException打断。直到今天,我们仍然时常为C#的Null或者VB的Nothing困惑。什么情况下我们该返回null,如果参数是null代表什么。许多类型,有两种不同意义的空状态,一种是null,一种是其本身或其某个属性集合中没有元素,这就更容易产生误用。常听有人说,Null这个概念在编程语言中根本不应该存在。但是,从C++到Java到.Net,它从未离开过。

最近,注意到.Net Framework在读取程序配置文件的一个小Bug。比如我在配置文件中,自定义了名为ReviewPeriod的节点:

01 <configuration>
02 <configSections>
03 <section name="reviewPeriod" type="WordPadTest.ReviewPeriod,WordPadTest"/>
04 </configSections>
05 <reviewPeriod>
06 <Periods>
07 <period id="1" />
08 <period id="2" name="d" />
09 <period id="3" name="m" />
10 </Periods>
11 </reviewPeriod>
12 </configuration>

注意第一个period节点没有定义name属性。.Net Framework中关于程序配置处理的类都在System.Configuration命名空间下,应用很广泛,比如Asp.Net和WCF项目,还有许多第三方框架如NHibernate。下面定义三个类,分别描述自定义节点配置,自定义节点集合,自定义节点实体,这也是最普通的程序自定义配置处理方式。然后就可以遍历ConfigurationManager.GetSection("reviewPeriod") as ReviewPeriod 访问每个period对象。

这段程序运行没问题,意外的是在第一个period节点上,它的Name属性是什么呢,一直以来我都弄错了,可能还有许多人也弄错了。正确答案是String.Empty,而不是null。而且即使我在ConfigurationProperty加上DefaultValue=null,Name返回的依然是String.Empty。

在我看来,null应该用于表示一种在我们预料之外的状态,包括传入的参数和返回的结果。比如一段从数据库读取记录的代码,如果执行中出现异常,则返回null,和正常执行后未找到任何匹配记录的情况截然不同。同理,对于节点的name属性未定义的情况,显然也不同于定义了name=”"的情况,返回null是合理的。而ConfigurationElement不允许string属性为null,可能有某方面的考虑,但这应该是个Bug,因为它返回值含混不清,是对string空值的误解。

请再来看另一个例子:如果这个返回值变成了参数的情况。在实际软件中,读取XML数据源时,通常要进行架构验证,比如像下面这样:

1 XmlReaderSettings settings = new XmlReaderSettings();
2 settings.Schemas.Add(targetNamespace, "postlist.xsd"); //targetNamespace是传入方法的参数
3 settings.ValidationType = ValidationType.Schema;
4 XmlReader reader = XmlReader.Create("postlist.xml", settings);

这段代码有一个问题,它未判断targetNamespace的是Null还是String.Empty。对于XmlSchemaSet的Add方法,targetNamespace参数如果为null,则表示使用xsd文件中定义的命名空间,而如果传入String.Empty,XmlSchemaSet依然认为,是我们手动指定了一个空的命名空间,而这完全不是我们想要的。

如果在xsd文件中定义了targetNamespace,我们手动指定的namespace必须与之一致,否则将抛出异常。而xsd文件中的targetNameSpace属性,你可以不加它,但加了就不允许空值。换句话说,我们传入的为String.Empty时targetNameSpace参数时,xsd中只要有targetNamespace的定义,程序必然出错。下图也是上面代码执行的结果,和传null值的情况有天壤之别。

image

我们不能怪罪写Xml验证的人太马虎,微软一个内部框架中就有这个问题。归根究底,是.Net Framework对null的误用,导致了我们的误解。

首先,ConfigurationElement类对返回值的误用,属性值该是null却返回String.Empty。

其次,XmlSchemaSet类的Add方法有一定问题,应该提供一个重载函数,不需要传入为null的targetNamespace参数,直接用xsd文件中的对应属性。 不但方便,也减少出错的机会。当然,它正确的区分了null和empty的含义,这点还是值得称赞的。

连.Net Framework对null使用上都有如此的问题,我们写程序时,应该更小心翼翼,对付这个难以捉摸、令人纠结的null。

分享到:
评论

相关推荐

    asp.net中对数据库表插入null空值的问题

    asp.net中对数据库表插入null空值的问题

    asp.net中Null在从数据库读取的时候的一点点小技巧

    它的功能很简单,就是说先在数据库里查找为Name的字段,然后进行判断,如果它的值为空的话,那么number的值就加1. 比如,加黑的就是我们需要注意下的。 代码如下: int number = 0; string connstr = @”Data Source=...

    VB.NET中的多线程开发

    对于使用VB6的开发者而言,要在程序中实现多线程(multi-thread)功能,一般就是使用Win32 API调用。但凡是进行过这种尝试的开发者都会感觉到实现过程非常困难,而且总是会发生些null terminated strings GPF的错误...

    解决asp.net mvc UpdateModel更新对象后出现null问题的方法

    项目中做了判断null不能提交更新到数据库中,所以导致一直提交不上去 后来网上查了一下找到了解决办法,我在这里分享一下,方便以后遇到这种情况的朋友可以方便解决 解决方法: 新建一个类继承DefaultModelBinder ...

    经典.NET笔试题 pdf版本

    21.在.net中,配件的意思是? 答:程序集。(中间语言,源数据,资源,装配清单) 22.常用的调用WebService的方法有哪些? 答:1.使用WSDL.exe命令行工具。 2.使用VS.NET中的Add Web Reference菜单选项 23..net ...

    spring.net+ibatis.net+mvc配置demo

    spring.net+ibatis.net+mvc配置demo.rar spring.net版本:1.3.2 ibatis.net版本:1.6.1 demo运行环境是VS2013 数据库表,我就没传了,测试的时候,建立表 CREATE TABLE [dbo].[Hair8_AD]( [ADId] [int] ...

    ASP.NET中读取excel内容,并显示在界面上

    NULL 博文链接:https://niunan.iteye.com/blog/274145

    如何在asp.net中使用unity

    NULL 博文链接:https://code.iteye.com/blog/1454019

    c# .net 兼容Excel2003与2007上传

    c# .net 兼容Excel2003与2007上传 IWorkbook wk =null; if (filename.IndexOf(".xlsx") &gt; 0) { wk = new XSSFWorkbook(fs); //把xlsx文件中的数据写入wk中 } else { wk = new HSSFWorkbook(fs); //把xls文件...

    .net中实现图片的横向(竖直)滚动(轮播)

    NULL 博文链接:https://long546324.iteye.com/blog/376673

    asp.net面试题3

    21.在.net中,配件的意思是? 答:程序集。(中间语言,源数据,资源,装配清单) 22.常用的调用WebService的方法有哪些? 答:1.使用WSDL.exe命令行工具。 2.使用VS.NET中的Add Web Reference菜单选项 23..net ...

    【ASP.NET编程知识】.NET Core 处理 WebAPI JSON 返回烦人的null为空.docx

    【ASP.NET编程知识】.NET Core 处理 WebAPI JSON 返回烦人的null为空.docx

    [ASP.NET.AJAX编程参考手册(涵盖ASP.NET.3.5及2.0)].(美)霍斯拉维.扫描版.pdf

    ASP.NET AJAX将ASP.NET/.NET Framework中的服务器端编程技术引入到客户端框架,从而带来了客户端编程的丰富特性。本书主要阐述ASP.NET AJAX是如何在客户端模拟这些丰富特性的。 本书通过大量实例、深入的描述以及...

    在 ASP.NET 中使用计时器执行用户代码(原创代码

    public static Timer gtimer = null; // 定义全局定时器类对象 public static int gcount = 0; // 测试用计时器变量 在 Global.asax 中的 Application_OnStart 事件过程中定义计时器,代码如下:。。。。。。。。...

    EasyPlat.Net快速开发平台源码20130805

    开发环境为Visual Studio 2010,数据库为SQL Server 2005,数据库文件在DB_51aspx文件夹中附加就行。 默认管理员登录名密码为:admin 123 更新历史 2013-08-03 1:在数据库表增加超级用户 root,admin 删除 APP_DATA...

    .Net Core2.1+NLog

    .Net Core2.1+NLog+数据库连接 &lt;?xml version="1.0" encoding="utf-8" ?&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" throwExceptions="true" internalLogLevel="warn" ...

    Spring.net框架

    在这个系列 中,我仅仅利用Sping.net这个框架向大家展示一下Ioc与AOP的强大功能(呵呵,其实写这段话的目的是因为“文章题目”牛皮吹得有点大了,给自 己个台阶下罢了)。 在这个系列中一共包含6个案例,从简单到...

    .Net Word文件操作Aspose.Words破解

    Type typeLic = null, typeIsTrial = null, typeHelper = null; foreach (var type in assembly.GetTypes()) { if ((typeLic == null) && (type.Name == stModule[0])) { typeLic = type; } else if (...

    Pro .NET Best Practices .net最佳实践 英文版

    书中总结了大量.NET开发人员公认的最佳实践,并有针对性地阐明了如何恰当地在个人、小组、组织和行业中应用这些最佳实践。书中的最佳实践涵盖.NET开发的方方面面,从基础技术到核心技术,从开发方法到开发流程,从...

Global site tag (gtag.js) - Google Analytics