C#中string比较方法的区别
在C#中比较string非常简单。 实际上有几种方法可以做到这一点。 我在下面的部分列出了一些。 我很好奇他们之间的区别,什么时候应该使用其他的? 应该不惜一切代价避免? 还有更多我没有列出?
string testString = "Test"; string anotherString = "Another"; if (testString.CompareTo(anotherString) == 0) {} if (testString.Equals(anotherString)) {} if (testString == anotherString) {}
(注意:我在这个例子中寻找的是平等的,不是小于或者大于,但也可以随意评论)
以下是这些function如何工作的规则:
stringValue.CompareTo(otherStringValue):
- null在string之前
- 它使用CultureInfo.CurrentCulture.CompareInfo.Compare,这意味着它将使用文化相关的比较。 这可能意味着ß将与德国的SS相当,或类似
stringValue.Equals(otherStringValue):
- null不被视为等于任何东西
- 除非你指定一个StringComparison选项,否则它将使用看起来像一个直接的序数相等性检查,即。 在任何语言或文化中,SS都不一样
stringValue == otherStringValue:
- 与stringValue.Equals()不一样。
- ==运算符调用静态Equals(stringa,stringb)方法(进而转到内部EqualsHelper进行比较。
- 对空string调用.Equals()会得到空引用exception,而on ==不会。
Object.ReferenceEquals(stringValue,otherStringValue):
只要检查参考是相同的,即。 它不仅仅是两个内容相同的string,而是将一个string对象与自己进行比较。
请注意,使用上述使用方法调用的选项,有重载和更多的选项来指定如何比较。
我的build议,如果你只是想检查平等是让你想想要使用文化依赖的比较或不,然后使用.CompareTo或.Equals,根据select。
来自MSDN:
“CompareTo方法主要用于sorting或字母sorting操作,当方法调用的主要目的是确定两个string是否相等时,不应使用CompareTo方法。要确定两个string是否相等,请调用Equals方法。 “
他们build议使用.Equals
而不是.CompareTo
当只是为了平等。 我不确定string
类是否有.Equals
和==
之间的区别。 我有时候会使用.Equals
或Object.ReferenceEquals
而不是==
为我自己的类,以防某些人稍后出现并重新定义该类的==
运算符。
如果你对BCL方法的差异感到好奇, Reflector是你的朋友:-)
我遵循这些准则:
完全匹配: 编辑:我以前总是使用==运算符的原则,内部等于(string,string)对象==运算符用于比较对象引用,但它似乎strA.Equals(strB)仍然是1-11%整体比string.Equals(strA,strB),strA == strB和string.CompareOrdinal(strA,strB)更快。 我使用StopWatch对interned / non-internedstring值进行循环testing,具有相同/不同的string长度以及不同的大小(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
正如Ed所说,CompareTo用于sorting。
.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);
简单的原因是下面会抛出一个exception:
string a = null; string b = "foo"; bool equal = a.Equals(b);
以下不会:
string a = null; string b = "foo"; bool equal = a == b;
关于string比较问题的好的解释和实践可以在文章“在Microsoft .NET 2.0中使用string的新build议”以及“ 在.NET Framework中使用string的最佳实践”中find 。
提到的每一种方法(和其他)都有特定的目的。 它们之间的主要区别在于它们默认使用了什么types的StringComparison枚举 。 有几个选项:
- 的CurrentCulture
- CurrentCultureIgnoreCase
- InvariantCulture的
- InvariantCultureIgnoreCase
- 序数词
- OrdinalIgnoreCase
以上每个比较types的目标不同的用例:
- 序数词
- 区分大小写的内部标识符
- 标准中的区分大小写的标识符,如XML和HTTP
- 区分大小写的安全相关设置
- OrdinalIgnoreCase
- 不区分大小写的内部标识符
- XML和HTTP等标准中不区分大小写的标识符
- 文件path(在Microsoft Windows上)
- registry项/值
- 环境variables
- 资源标识符(例如句柄名称)
- 不区分大小写的安全相关设置
- InvariantCulture或InvariantCultureIgnoreCase
- 一些坚持语言相关的数据
- 显示需要固定sorting顺序的语言数据
- CurrentCulture或CurrentCultureIgnoreCase
- 数据显示给用户
- 大多数用户input
请注意, StringComparison枚举以及string比较方法的重载,自.NET 2.0以来就存在。
String.CompareTo方法(string)
其实是IComparable.CompareTo方法的types安全实现。 默认解释:CurrentCulture。
用法:
CompareTo方法主要用于sorting或字母sorting操作
从而
实现IComparable接口将必然使用这种方法
String.Compare方法
一个String类的静态成员,有许多重载。 默认解释:CurrentCulture。
只要有可能,就应该调用包含StringComparison参数的Compare方法的重载。
String.Equals方法
从Object类中覆盖并重载以保证types安全。 默认解释:序数。 请注意:
String类的相等方法包括静态Equals , 静态运算符==和实例方法Equals 。
StringComparer类
还有另一种处理string比较的方法,特别是针对sorting:
您可以使用StringComparer类创build特定types的比较,以对generics集合中的元素进行sorting。 类如Hashtable,Dictionary,SortedList和SortedList使用StringComparer类进行sorting。
并不是说性能通常与99%的时间需要这么做有关系,但是如果你必须在循环中做数百万次,我会强烈build议你使用.Equals或==,因为只要它find一个字符不匹配它会把整个事件抛出为false,但是如果使用CompareTo,则必须找出哪个字符小于另一个字符,导致稍微差一点的性能时间。
如果你的应用程序将运行在不同的国家,我build议你看一下CultureInfo的含义,并可能使用.Equals。 由于我只是真的写美国的应用程序(并不关心,如果它不能正常工作),我总是使用==。
在这里列出的表格中,两者没有太大的区别。 CompareTo
最终调用一个CompareInfo
方法,使用当前的文化进行比较; Equals
由==
运算符调用。
如果你考虑过重,那么事情就会变得不同。 Compare
和==
只能使用当前的文化来比较一个string。 Equals
和String.Compare
可以使用一个StringComparison
枚举参数,让您指定不区分大小写或不区分大小写的比较。 只有String.Compare
允许你指定一个CultureInfo
并使用非默认文化进行比较。
由于其通用性,我发现我比其他任何比较方法都使用了String.Compare
。 它让我指定我想要的。
一个重要的区别是.Equals()会抛出一个exception,如果第一个string为空,Whereas ==不会。
string s = null; string a = "a"; //Throws {"Object reference not set to an instance of an object."} if (s.Equals(a)) Console.WriteLine("s is equal to a"); //no Exception if(s==a) Console.WriteLine("s is equal to a");
使用.Equals也更容易阅读 。
CompareTo
将string与string对象进行比较,并返回一个int值。 如果该值为0,则表示string相等。
string country = "southindia"; object ob1 = country.Clone(); Console.WriteLine( country.CompareTo(ob1)); string country = "southindia"; string cou = "insia"; int n = country.CompareTo(cou); Console.WriteLine( n );
与.Equals,你也获得StringComparison选项。 非常方便无视案件和其他事情。
顺便说一句,这将评估为假
string a = "myString"; string b = "myString"; return a==b
由于==比较了a和b(它们是指针)的值,只有当指针指向内存中的同一个对象时,才会计算为真。 .Equals解引用指针并比较存储在指针处的值。 a.Equals(b)在这里将是真实的。
如果您将b更改为:
b = "MYSTRING";
那么a.Equals(b)是错误的,但是
a.Equals(b, StringComparison.OrdinalIgnoreCase)
将是真实的
a.CompareTo(b)调用string的CompareTo函数,该函数比较指针处的值,如果a处存储的值小于b处存储的值,则返回<0;如果a.Equals(b)为true,则返回0;否则为0。 但是,这是区分大小写的,我认为可能有CompareTo的选项来忽略大小写,但是现在没有时间去查看。 正如其他人已经指出,这将做分拣。 以这种方式比较平等会导致不必要的开销。
我敢肯定,我会把东西丢掉,但是我认为这应该是足够的信息来开始试验,如果你需要更多的细节。