判断字符串是否为空串的技巧
本文写作缘起于阮的讨论——《FxCop告诉我,检查一个字符串是否为空要用string.Length。》。其实用过FxCop的人都知道它会建议你使用String.Length属性来判断字符串是否为空串,但你又是否明白其中的缘由呢?今天有点闲,特意写下这篇文章,希望有点帮助。1. 三种常用的字符串判空串方法:
- Length法:bool isEmpty = (str.Length == 0);
- Empty法:bool isEmpty = (str == String.Empty);
- General法:bool isEmpty = (str == "");
2. 深入内部机制:
-
要探讨这三种方法的内部机制,我们得首先看看.NET是怎样实现的,也就是要看看.NET的源代码!然而,我们哪里找这些源代码呢?我们同样有三种方法:
- Rotor法:一个不错的选择就是微软的Rotor,这是微软的一个源代码共享项目。
- Mono法:另一个不错的选择当然就是真正的开源项目Mono啦!
- Reflector法:最后一个选择就是使用反编译器,不过这种重组的代码不一定就是原貌,只不过是一种“近似值”,你可以考虑使用Reflector这个反编译器[1]。
- 这里我采用Reflector法,我们先来看看一下源代码[2](片段):
- Rotor里面String类的代码与此没什么不同,只是没有EqualsHelper方法,代之以如下的声明:
-
进一步分析:
- 首先是Empty法,由于String.Empty是一个静态只读域,只会被创建一次(在静态构造函数中)。但当我们使用Empty法进行判空时,.NET还会依次展开调用以下的方法,而后两个方法内部还会进行对象引用判等!
-
- 若使用General法判等的话,情况就“更胜一筹”了!因为.NET除了要依次展开调用上面三个方法之外,还得首先创建一个临时的空字符串实例,如果你要进行大量的比较,这恐怕是想一想就很吓人了!
- 而对于Length法,我们就可以绕过上面这些繁琐的步骤,直接进行整数(字符串长度)判等,我们知道,大多数情况下,整数判等都要来得快(我实在想不出比它更快的了,在32位系统上,System.Int32运算最快了)!
- 另外,我们还可以看到,在EqualsHelper方法里面.NET会先使用Length法来进行判等!可惜的是我无法获得InternalLength方法的代码。但我在Mono的源代码里面看到更简明的实现:
-
- 然而使用Length法进行字符串判空串时,有一点要注意的,就是你必须先判断该字符串实例是否为空引用,否则将会抛出NullReferenceException异常!于是,我们有了一个经过改进的Length法:
3. 最后总结:
从上面的分析我们可以看到,使用Length法来进行字符串判空串是有着很大的性能优势的,尤其在进行大量字符串判空时!当然首先得判断字符串实例是否为空引用!
- 有关Reflector的介绍可以参见《Reflector: Get the secret inside .NET assemblies.》一文。
- 本代码反编译自版本号为2.0.3600.0的.NET Framework。
posted on 2004-11-11 18:20 Allen Lee 阅读(4341) 评论(13) 编辑收藏 引用 收藏至365Key 所属分类: C#
2004-11-11 23:06 geel
voidFoo(stringbar)
{
if((bar!=null)&&(bar.Length==0))
//
}
{
if((bar!=null)&&(bar.Length==0))
//
}
classString
{
privateintlength;
publicintLength
{
get
{
returnlength;
}
}
//.
}
{
privateintlength;
publicintLength
{
get
{
returnlength;
}
}
//.
}
publicstaticbooloperator==(stringa,stringb);
publicstaticboolEquals(stringa,stringb);
privatestaticunsafeboolEqualsHelper(stringao,stringbo);
publicstaticboolEquals(stringa,stringb);
privatestaticunsafeboolEqualsHelper(stringao,stringbo);
publicexternboolEquals(Stringvalue);
publicsealedclassString:IComparable,ICloneable,IConvertible,IEnumerable,IComparable<string>
{
staticString()
{
string.Empty="";
//Codehere
}
//Codehere
publicstaticreadonlystringEmpty;
publicstaticbooloperator==(stringa,stringb)
{
returnstring.Equals(a,b);
}
publicstaticboolEquals(stringa,stringb)
{
if(a==b)
{
returntrue;
}
if((a!=null)&&(b!=null))
{
returnstring.EqualsHelper(a,b);
}
returnfalse;
}
privatestaticunsafeboolEqualsHelper(stringao,stringbo)
{
//Codehere
intnum1=ao.Length;
if(num1!=bo.Length)
{
returnfalse;
}
//Codehere
}
privateexternintInternalLength();
publicintLength
{
get
{
returnthis.InternalLength();
}
}
//Codehere
}
{
staticString()
{
string.Empty="";
//Codehere
}
//Codehere
publicstaticreadonlystringEmpty;
publicstaticbooloperator==(stringa,stringb)
{
returnstring.Equals(a,b);
}
publicstaticboolEquals(stringa,stringb)
{
if(a==b)
{
returntrue;
}
if((a!=null)&&(b!=null))
{
returnstring.EqualsHelper(a,b);
}
returnfalse;
}
privatestaticunsafeboolEqualsHelper(stringao,stringbo)
{
//Codehere
intnum1=ao.Length;
if(num1!=bo.Length)
{
returnfalse;
}
//Codehere
}
privateexternintInternalLength();
publicintLength
{
get
{
returnthis.InternalLength();
}
}
//Codehere
}
本文地址:http://www.45fan.com/a/question/72890.html
评论
谢谢!受益匪浅回复
#re: 如何判断字符串是否为空串? 2004-11-12 08:34 Ninputer
等于null一般我也认为是空的,所以我常用
if ((s == null)||(s.Length == 0))回复
#re: 如何判断字符串是否为空串? 2004-11-12 09:13 montaque
这点差异,对一般的应用没啥大的影响。
应用的瓶颈往往不在你采用一个小的优化。
当然写程序的时候,我跟 ninputer 一样;)回复
#re: 如何判断字符串是否为空串? 2004-11-12 09:14 montaque
框架警察重这也是一个checkpoint回复
#re: 如何判断字符串是否为空串? 2004-11-12 11:07 Allen Lee
To Ninputer:
的确,如果你把字符串为null和""都看成不是期望的数据时,使用你的方式来工作有更好的效果。只有s不为null的前提下,.NET才会进一步计算s.Length是否为0,最后综合给出逻辑运算结果。回复
#re: 如何判断字符串是否为空串? 2004-11-12 13:47 阮
这个正是我想要知道的,非常感谢Allen Lee。回复
#re: 如何判断字符串是否为空串?[C#] 2004-11-12 23:53 Samuel
Good staff.
You have took a deep think.
But , the string must be not null first.回复
#re: 如何判断字符串是否为空串?[C#] 2004-11-13 11:23 Allen Lee
To Samuel:
Yes, sometime we must ensure that the strings we get are not null first for some methods will return null values in some case.
But most of the time we retrieve the strings from UI controls and almost all UI controls will return an Empty string if there is no input by users. In this case, we can simply validate whether the strings we get are Empty.
What's more, most programmer will treat both null value string and Empty value string as unexpected data, so we recommend that you use the following way to validate the data you get:
if ((str == null) || (str.Length == 0))
DoSomething();
because C-Base Language like C# will caculate the latter condition (here is str.Length == 0) just when the former condition (here is str == null) is false when we use the || operator. And finally, just when all the subcondition result in false (then the whole condition is false) will the DoSomething method be run.
Thanks for your comments and I hope my comments will give you a hand too.
回复
#re: 如何判断字符串是否为空串?[C#] 2004-11-24 19:04 Allen Lee
点评:
用过FxCop的人都知道它会建议你使用String.Length属性来判断字符串是否为空串,但你又是否明白其中的缘由呢?本文将通过对比常用比较方法的内部机理为你解开疑惑。回复
#re: 如何判断字符串是否为空串?[C#] 2004-12-23 21:29 cboy
有道理回复
#re: 如何判断字符串是否为空串?[C#] 2005-08-31 10:17 Sandheart
那要判断一个字符串不为空的话应该这样写吧:
void Foo(string bar)
{
if ((bar != null) && (bar.Length > 0))
//
}回复
#re: 如何判断字符串是否为空串?[C#] 2005-11-15 09:54 VortexDragon(旋风龙)
不错。回复
#re: 如何判断字符串是否为空串?[C#] 2005-11-17 08:20 wangth68
真是受益得很。回复