当前位置:  开发笔记 > 编程语言 > 正文

C#中字符串比较方法的差异

如何解决《C#中字符串比较方法的差异》经验,为你挑选了7个好方法。

在C#中比较字符串非常简单.事实上,有几种方法可以做到这一点.我在下面的块中列出了一些.我很好奇的是它们之间的差异以及何时应该使用其他的?是否应该不惜一切代价避免?还有更多我没有列出?

string testString = "Test";
string anotherString = "Another";

if (testString.CompareTo(anotherString) == 0) {}
if (testString.Equals(anotherString)) {}
if (testString == anotherString) {}

(注意:我在这个例子中寻找平等,不小于或大于,但也可以随意发表评论)



1> angry person..:

以下是这些功能如何工作的规则:

stringValue.CompareTo(otherStringValue)

    null 来自一个字符串

    它使用CultureInfo.CurrentCulture.CompareInfo.Compare,这意味着它将使用文化相关的比较.这可能意味着ßSS在德国或类似地进行比较

stringValue.Equals(otherStringValue)

    null 被认为不等于任何东西

    除非您指定StringComparison选项,否则它将使用看起来像直接序数相等检查的内容,即ßSS任何语言或文化中的相同

stringValue == otherStringValue

    是不一样的stringValue.Equals().

    ==运营商调用静态Equals(string a, string b)方法(这反过来又转到内部EqualsHelper做比较.

    调用.Equals()一个null字符串被null引用异常,同时==没有.

Object.ReferenceEquals(stringValue, otherStringValue)

只检查引用是否相同,即它不只是具有相同内容的两个字符串,而是将字符串对象与自身进行比较.


请注意,使用上面使用方法调用的选项,有一些重载,有更多选项来指定如何比较.

如果你只是想检查是否平等,我的建议就是决定是否要使用依赖于文化的比较,然后使用.CompareTo.Equals取决于选择.


==与.Equals()不同... ==运算符调用静态Equals(字符串a,字符串b)方法(后者又转到内部EqualsHelper进行比较.在null上调用.Equals string获取null引用exc.而on = =不.
"stringValue.Equals(otherStringValue):null不等于null"Lol,我不是说.null等于ObjectReferenceNotSet异常.
另一方面,.Equals稍快(内部少一个方法调用),但可读性较低 - 当然可以说:).

2> Ed S...:

来自MSDN:

"CompareTo方法主要用于排序或字母顺序操作.当方法调用的主要目的是确定两个字符串是否相同时,不应使用它.要确定两个字符串是否相等,请调用Equals方法. "

他们建议使用.Equals而不是.CompareTo仅仅寻求平等.我不知道是否有之间的差异.Equals,并==string类.我有时会使用.EqualsObject.ReferenceEquals代替==我自己的类,以防有人稍后出现并重新定义==该类的运算符.


那件事发生在你身上吗?(重新定义==)......我认为这是waaaay太防御性编程=)

3> 小智..:

如果您对BCL方法的差异感到好奇,Reflector就是您的朋友:-)

我遵循以下准则:

完全匹配: 编辑:我以前总是使用==运算符,原理是在Equals(字符串,字符串)内,对象==运算符用于比较对象引用,但似乎strA.Equals(strB)仍然是1-11%总体上比string.Equals(strA,strB),strA == strB和string.CompareOrdinal(strA,strB)更快.我在Interned/non-interned字符串值上使用StopWatch进行循环测试,具有相同/不同的字符串长度和不同的大小(1B到5MB).

strA.Equals(strB)

人类可读的匹配(西方文化,不区分大小写):

string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0

人类可读的匹配(CultureInfo定义的所有其他文化,不敏感的案例/重音/假名/等):

string.Compare(strA, strB, myCultureInfo) == 0

人工可读的自定义规则(所有其他文化):

CompareOptions compareOptions = CompareOptions.IgnoreCase
                              | CompareOptions.IgnoreWidth
                              | CompareOptions.IgnoreNonSpace;
string.Compare(strA, strB, CultureInfo.CurrentCulture, compareOptions) == 0



4> Jonathan C D..:

正如Ed所说,CompareTo用于排序.

但是,.Equals和==之间存在差异.

==解析为基本上以下代码:

if(object.ReferenceEquals(left, null) && 
   object.ReferenceEquals(right, null))
    return true;
if(object.ReferenceEquals(left, null))
    return right.Equals(left);
return left.Equals(right);

简单的原因是以下将抛出异常:

string a = null;
string b = "foo";

bool equal = a.Equals(b);

以下不会:

string a = null;
string b = "foo";

bool equal = a == b;



5> Ryszard Dżeg..:

有关字符串比较问题的详细解释和实践可以在Microsoft .NET 2.0中使用字符串的新建议文章以及.NET Framework中使用字符串的最佳实践中找到.


所提到的每种方法(和其他)都有特定的目的.它们之间的主要区别在于它们默认使用的是哪种StringComparison枚举.有几种选择:

的CurrentCulture

CurrentCultureIgnoreCase

InvariantCulture的

InvariantCultureIgnoreCase

序数词

OrdinalIgnoreCase

以上每种比较类型都针对不同的用例:

序数词

区分大小写的内部标识符

XML和HTTP等标准中的区分大小写的标识符

区分大小写的安全相关设置

OrdinalIgnoreCase

不区分大小写的内部标识符

XML和HTTP等标准中的不区分大小写的标识符

文件路径(在Microsoft Windows上)

注册表项/值

环境变量

资源标识符(例如,句柄名称)

不区分大小写的安全相关设置

InvariantCulture或InvariantCultureIgnoreCase

一些持久的语言相关数据

显示需要固定排序顺序的语言数据

CurrentCulture或CurrentCultureIgnoreCase

显示给用户的数据

大多数用户输入

请注意,自.NET 2.0以来,存在StringComparison枚举以及字符串比较方法的重载.


String.CompareTo方法(String)

实际上是IComparable.CompareTo方法的类型安全实现.默认解释:CurrentCulture.

用法:

CompareTo方法主要用于排序或字母顺序操作

从而

实现IComparable接口必然会使用此方法

String.Compare方法

String Class的静态成员,具有许多重载.默认解释:CurrentCulture.

只要有可能,您应该调用包含StringComparison参数的Compare方法的重载.

String.Equals方法

从Object类重写并重载以确保类型安全.默认解释:序数.请注意:

String类的相等方法包括静态Equals,静态运算符==实例方法Equals.


StringComparer类

还有另一种处理字符串比较的方法,特别是旨在排序:

您可以使用StringComparer类创建特定于类型的比较,以对通用集合中的元素进行排序.诸如Hashtable,Dictionary,SortedList和SortedList之类的类使用StringComparer类进行排序.


根据SO上的其他一些帖子,除了序数之外的所有方法都有比较(a,b)和比较(b,a)都可以返回1的情况,并且该bug被归类为"将不会被修复".因此,我不确定任何此类比较都有*任何*用例.

6> viggity..:

并非性能通常在99%的时间内都很重要,但是如果你必须循环数百万次,我强烈建议您使用.Equals或==因为一旦找到一个字符与它不匹配的东西将整个东西抛出为假,但是如果你使用CompareTo它将必须弄清楚哪个字符小于另一个,导致稍差的性能时间.

如果您的应用程序将在不同的国家/地区运行,我建议您查看CultureInfo含义并可能使用.Equals.因为我只为美国编写应用程序(并且不关心某人是否无法正常工作),所以我总是只使用==.



7> OwenP..:

在这里列出的表格中,两者之间没有太大区别. CompareTo最终调用一个CompareInfo使用当前文化进行比较的方法; Equals==运营商召集.

如果你考虑过载,那么情况会有所不同. Compare并且==只能使用当前文化来比较字符串. Equals并且String.Compare可以使用StringComparison枚举参数,该参数允许您指定对文化不敏感或不区分大小写的比较.仅String.Compare允许您CultureInfo使用默认区域性以外的区域性来指定和执行比较.

由于它的多功能性,我发现我使用的String.Compare比任何其他比较方法更多; 它让我准确指出我想要的东西.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有