比较C#中的字符串非常简单。事实上,有几种方法可以做到这一点。我在下面的块中列出了一些。我感到好奇的是它们之间的区别以及何时应该使用其他区别?是否应该不惜一切代价避免?还有更多我没有列出?
string testString = "Test";
string anotherString = "Another";
if (testString.CompareTo(anotherString) == 0) {}
if (testString.Equals(anotherString)) {}
if (testString == anotherString) {}
(注意:我在这个例子中寻找平等,不小于或大于,但也可以随意发表评论)
答案 0 :(得分:219)
以下是这些功能如何运作的规则:
<强> 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
,具体取决于选择。
答案 1 :(得分:70)
来自MSDN:
“CompareTo方法主要用于排序或 按字母顺序排列的操作。主要时不应该使用它 方法调用的目的是确定是否有两个字符串 当量。要确定两个字符串是否相同,请调用 等于方法。“
他们建议在仅仅考虑平等时使用.Equals
而不是.CompareTo
。我不确定.Equals
类==
和string
之间是否存在差异。我有时会为自己的班级使用.Equals
或Object.ReferenceEquals
代替==
,以防有人稍后出现并重新定义该班级的==
运算符。
答案 2 :(得分:50)
如果您对BCL方法的差异感到好奇,Reflector是您的朋友: - )
我遵循以下准则:
完全匹配: 编辑:我之前总是使用==运算符,其原理是在Equals(string,string)内对象==运算符用于比较对象引用但它似乎strA.Equals(strB)总体上比string.Equals(strA,strB),strA == strB和string.CompareOrdinal(strA,strB)快1-11%。我在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
答案 3 :(得分:18)
正如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;
答案 4 :(得分:15)
有关字符串比较问题的详细解释和做法可以在文章New Recommendations for Using Strings in Microsoft .NET 2.0和Best Practices for Using Strings in the .NET Framework中找到。
每个提到的方法(和其他)都有特殊目的。它们之间的关键区别在于它们默认使用的是StringComparison Enumeration。有几种选择:
以上每种比较类型都针对不同的用例:
请注意,自.NET 2.0以来,存在StringComparison Enumeration以及字符串比较方法的重载。
实际上是IComparable.CompareTo Method的类型安全实现。默认解释:CurrentCulture。
用法:
CompareTo方法主要用于排序或按字母顺序排列操作
因此
实现IComparable接口必然会使用此方法
String Class的静态成员,它有许多重载。默认解释:CurrentCulture。
只要有可能,您应该调用包含StringComparison参数的Compare方法的重载。
从Object类重写并为类型安全重载。默认解释:序数。 请注意:
String类的相等方法包括静态等于,静态运算符== 和实例方法等于。
还有另一种处理字符串比较的方法,特别是要排序:
您可以使用StringComparer class创建特定于类型的比较,以对通用集合中的元素进行排序。 Hashtable,Dictionary,SortedList和SortedList等类使用StringComparer类进行排序。
答案 5 :(得分:7)
并非性能通常在99%的时间内都很重要,但是如果你必须在一个循环中这样做几百万次,我强烈建议你使用.Equals或==因为它一旦它发现一个与它不匹配的字符会将整个事情抛出为假,但是如果你使用CompareTo,它必须弄清楚哪个字符小于另一个字符,导致性能时间稍差。
如果您的应用将在不同的国家/地区运行,我建议您查看CultureInfo含义,并可能使用.Equals。由于我只为美国编写应用程序(并不关心某人是否无法正常使用),我总是只使用==。
答案 6 :(得分:5)
在此处列出的表单中,两者之间没有太大区别。 CompareTo
最终调用CompareInfo
方法,使用当前文化进行比较; Equals
运营商会调用==
。
如果你考虑过载,那么情况会有所不同。 Compare
和==
只能使用当前文化来比较字符串。 Equals
和String.Compare
可以使用StringComparison
枚举参数,您可以指定区分大小写或不区分大小写的比较。只有String.Compare
允许您指定CultureInfo
并使用默认文化以外的文化进行比较。
由于它的多功能性,我发现我使用String.Compare
比任何其他比较方法更多;它让我准确指出我想要的东西。
答案 7 :(得分:2)
要注意的一个重要区别是.Equals()如果第一个字符串为null则抛出异常,而= =不会。
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");
答案 8 :(得分:0)
答案 9 :(得分:-1)
使用.Equals也更容易阅读。
答案 10 :(得分:-9)
使用.Equals,您还可以获得StringComparison选项。忽略案件和其他事情非常方便。
顺便说一句,这将评估为假
string a = "myString";
string b = "myString";
return a==b
由于==比较a和b(它们是指针)的值,如果指针指向内存中的同一个对象,这将仅计算为true。 .Equals取消引用指针并比较指针中存储的值。 a.Equals(b)在这里是真的。
如果您将b更改为:
b = "MYSTRING";
然后a.Equals(b)是假的,但是
a.Equals(b, StringComparison.OrdinalIgnoreCase)
会是真的
a.CompareTo(b)调用字符串的CompareTo函数,该函数比较指针处的值,如果存储在a处的值小于存储在b处的值,则返回&lt; 0,如果a.Equals(b)则返回0为真,否则为> 0。但是,这是区分大小写的,我认为CompareTo可能有一些选项可以忽略大小写,但是现在没有时间看。 正如其他人已经说过的那样,这将用于分类。以这种方式比较相等会导致不必要的开销。
我确定我要把东西丢掉,但我认为如果你需要更多的细节,这应该是足够的信息来开始试验。