C#中字符串的比较操作
2012-03-23 13:55
363 查看
字符串比较是比较常用的操作,一般出于以下两个原因比较字符串:
判断相等字符串排序
查询API判断字符串相等或排序时,由以下方法:
publicoverrideboolEquals(objectobj); publicboolEquals(stringvalue); publicstaticboolEquals(stringa,stringb); publicboolEquals(stringvalue,StringComparisoncomparisonType); publicstaticboolEquals(stringa,stringb,StringComparisoncomparisonType); publicstaticintCompare(stringstrA,stringstrB); publicstaticintCompare(stringstrA,stringstrB,boolignoreCase); publicstaticintCompare(stringstrA,stringstrB,StringComparisoncomparisonType); publicstaticintCompare(stringstrA,stringstrB,boolignoreCase,CultureInfoculture); publicstaticintCompare(stringstrA,stringstrB,CultureInfoculture,CompareOptionsoptions); publicstaticintCompare(stringstrA,intindexA,stringstrB,intindexB,intlength); publicstaticintCompare(stringstrA,intindexA,stringstrB,intindexB,intlength,boolignoreCase); publicstaticintCompare(stringstrA,intindexA,stringstrB,intindexB,intlength,StringComparisoncomparisonType); publicstaticintCompare(stringstrA,intindexA,stringstrB,intindexB,intlength,boolignoreCase,CultureInfoculture); publicstaticintCompare(stringstrA,intindexA,stringstrB,intindexB,intlength,CultureInfoculture,CompareOptionsoptions); publicstaticintCompareOrdinal(stringstrA,stringstrB); publicstaticintCompareOrdinal(stringstrA,intindexA,stringstrB,intindexB,intlength); publicintCompareTo(objectvalue); publicintCompareTo(stringstrB);
发现上述的方法中大多都有StringComparison类型的枚举,查询msdn后得到:
现简单写一段代码,测试Compare(stringstrA,stringstrB,StringComparisoncomparisonType)方法。分别用到StringComparison.CurrentCulture和StringComparison.Ordinal。代码如下:
staticvoidMain(string[]args) { stringstrA="asdfadsfasdfew我ò啊?地?方?的?asd"; stringstrB="adsfeaqfaead啊?多à发¢安2德?森-efadsfa"; Stopwatchsw=newStopwatch(); sw.Start(); for(inti=0;i<1000000;i++) { string.Compare(strA,strB,StringComparison.CurrentCulture); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); for(inti=0;i<1000000;i++) { string.Compare(strA,strB,StringComparison.Ordinal); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); for(inti=0;i<1000000;i++) { string.CompareOrdinal(strA,strB); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); }
执行结果如下:
测试结果非常明显,StringComparison.Currentculture显式传递了当前语言文化,而传递了String.Ordinal则会忽略指定的语言文化,这是执行字符串最快的一种方式。
使用.NETReflector查看源代码:
publicstaticintCompare(stringstrA,stringstrB,StringComparisoncomparisonType) { if((comparisonType<StringComparison.CurrentCulture)||(comparisonType>StringComparison.OrdinalIgnoreCase)) { thrownewArgumentException(Environment.GetResourceString("NotSupported_StringComparison"),"comparisonType"); } if(strA==strB) { return0; } if(strA==null) { return-1; } if(strB==null) { return1; } switch(comparisonType) { caseStringComparison.CurrentCulture: returnCultureInfo.CurrentCulture.CompareInfo.Compare(strA,strB,CompareOptions.None); caseStringComparison.CurrentCultureIgnoreCase: returnCultureInfo.CurrentCulture.CompareInfo.Compare(strA,strB,CompareOptions.IgnoreCase); caseStringComparison.InvariantCulture: returnCultureInfo.InvariantCulture.CompareInfo.Compare(strA,strB,CompareOptions.None); caseStringComparison.InvariantCultureIgnoreCase: returnCultureInfo.InvariantCulture.CompareInfo.Compare(strA,strB,CompareOptions.IgnoreCase); caseStringComparison.Ordinal: returnCompareOrdinalHelper(strA,strB); caseStringComparison.OrdinalIgnoreCase: if(!strA.IsAscii()||!strB.IsAscii()) { returnTextInfo.CompareOrdinalIgnoreCase(strA,strB); } returnCompareOrdinalIgnoreCaseHelper(strA,strB); } thrownewNotSupportedException(Environment.GetResourceString("NotSupported_StringComparison")); }
在上例中,同时测试了String的CompareOrdinal方法,效率同样惊人。查看其源代码后发现与Compare方法String.Ordinal源代码一样,此方法只是Compare方法的一个特例:
publicstaticintCompareOrdinal(stringstrA,stringstrB)
{
if(strA==strB)
{
return0;
}
if(strA==null)
{
return-1;
}
if(strB==null)
{
return1;
}
returnCompareOrdinalHelper(strA,strB);
}
接下来看看String.CompareTo()方法的源代码:
[TargetedPatchingOptOut("PerformancecriticaltoinlineacrossNGenimageboundaries")]
publicintCompareTo(stringstrB)
{
if(strB==null)
{
return1;
}
returnCultureInfo.CurrentCulture.CompareInfo.Compare(this,strB,CompareOptions.None);
}
与类型参数为StringComparison.CurrentCulture的Compare方法相同。
另外StringComparer也实现了字符串比较方法Compare()方法。直接看源代码:
publicintCompare(objectx,objecty)
{
if(x==y)
{
return0;
}
if(x==null)
{
return-1;
}
if(y==null)
{
return1;
}
stringstr=xasstring;
if(str!=null)
{
stringstr2=yasstring;
if(str2!=null)
{
returnthis.Compare(str,str2);
}
}
IComparablecomparable=xasIComparable;
if(comparable==null)
{
thrownewArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
}
returncomparable.CompareTo(y);
}
如果程序只将字符串用于内部编码目的,如路径名、文件名、URL、环境变量、反射、XML标记等,这些字符串通常只在程序内部使用,不会像用户展示,应该使用String.Ordinal或者使用String.CompareOrdinal()方法
总结及建议:
使用显示地指定了字符串比较规则的重载函数。一般来说,需要带有StringComparison类型参数的重载函数
在对未知文化的字符串做比较时,使用StringComparison.Ordinal和StringComparison.OrdinallgnoreCase作为默认值,提高性能
在像用户输出结果时,使用基于StringComparison.CurrentCulture的字符串
使用String.Equals的重载版本来测试两个字符串是否相等。
不要使用String.Compare或CompareTo的重载版本来检测返回值是否为0来判断字符串是否相等。这两个函数是用于字符串比较,而非检查相等性。
在字符串比较时,应以String.ToUpperInvariant函数使字符串规范化,而不用ToLowerInvariant方法,因为Microsoft对执行大写比较的代码进行了优化。之所以不用ToUpper和ToLower方法,是因为其对语言文化敏感。
相关文章推荐
- C#字符串比较及截取子字符串的操作
- C#中字符串的比较操作
- 实例比较C#与C++字符串操作
- C#操作JSON字符串
- 比较高效的javaseript字符串连接操作
- C# 字符串操作
- [C#]字符串比较--显示相同[In VS],比较结果却不同
- C#优化字符串操作(清清月儿)
- C#优化字符串操作(7)--输出21个AAAAAAAAAAAAAAAAAAAAA的巧妙做法
- 【JAVA与C#比较】ORM操作数据库
- C#字符串操作总结
- Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
- c#字符串及数组操作
- C# Excel 行高,列宽,合并单元格,单元格边框线,冻结(转载) - 关于C#操作EXCLE常见操作比较全的 (防找不到)
- 谈c++ 和 c#关于字符串和其它类型的相加操作
- C#中比较字符串的方法
- Unity3D C#对字符串的操作
- perl里字符串取长度,比较等一些操作
- C#中判断字符串为空的几种方法的比较
- C# 中对字符串的操作