C# 为什么要在 == 上使用 String.Equals?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1659097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why would you use String.Equals over ==?
提问by JamesBrownIsDead
I recently was introduced to a large codebase and noticed all string comparisons are done using String.Equals()
instead of ==
我最近被介绍到一个大型代码库,并注意到所有字符串比较都是使用String.Equals()
而不是==
What's the reason for this, do you think?
这是什么原因,你觉得呢?
回答by Jorge Israel Pe?a
There's a writeup on this articlewhich you might find to be interesting, with some quotes from Jon Skeet. It seems like the use is pretty much the same.
有一个书面记录这篇文章,你可能会发现很有趣,从乔恩斯基特一些报价。好像用法差不多。
Jon Skeet states that the performance of instance Equals "is slightly better when the strings are short—as the strings increase in length, that difference becomes completely insignificant."
Jon Skeet 指出,实例 Equals 的性能“当字符串较短时会稍微好一些——随着字符串长度的增加,这种差异变得完全无关紧要。”
回答by Matthew Scharley
It's entirely likely that a large portion of the developer base comes from a Java background where using ==
to compare strings is wrong and doesn't work.
很可能大部分开发人员都来自 Java 背景,其中使用==
比较字符串是错误的并且不起作用。
In C# there's no (practical) difference (for strings) as long as they are typed as string.
在 C# 中,只要将它们输入为字符串,就没有(实际的)区别(对于字符串)。
If they are typed as object
or T
then see other answers here that talk about generic methods or operator overloading as there you definitely want to use the Equals method.
如果它们被输入为object
或T
然后在这里看到其他讨论泛型方法或运算符重载的答案,因为在那里你肯定想使用 Equals 方法。
回答by Michael Petrotta
String.Equals
does offer overloads to handle casing and culture-aware comparison. If your code doesn't make use of these, the devs may just be used to Java, where (as Matthew says), you must use the .Equals method to do content comparisons.
String.Equals
确实提供了处理大小写和文化感知比较的重载。如果您的代码不使用这些,开发人员可能只是习惯于 Java,其中(如 Matthew 所说),您必须使用 .Equals 方法进行内容比较。
回答by thezar
Both methods do the same functionally- they compare values.
As is written on MSDN:
这两种方法在功能上都是一样的——它们比较值。
正如 MSDN 上所写:
- About
String.Equals
method - Determines whether this instance and another specified String object have the same value. (http://msdn.microsoft.com/en-us/library/858x0yyx.aspx) - About
==
- Although string is a reference type, the equality operators (==
and!=
) are defined to compare the values of string objects, not references. This makes testing for string equality more intuitive. (http://msdn.microsoft.com/en-en/library/362314fe.aspx)
- 关于
String.Equals
方法 - 确定此实例和另一个指定的 String 对象是否具有相同的值。( http://msdn.microsoft.com/en-us/library/858x0yyx.aspx) - 关于
==
- 尽管 string 是引用类型,但定义了相等运算符 (==
和!=
) 来比较字符串对象的值,而不是引用。这使得对字符串相等性的测试更加直观。( http://msdn.microsoft.com/en-en/library/362314fe.aspx)
But if one of your string instances is null, these methods are working differently:
但是,如果您的字符串实例之一为空,则这些方法的工作方式不同:
string x = null;
string y = "qq";
if (x == y) // returns false
MessageBox.Show("true");
else
MessageBox.Show("false");
if (x.Equals(y)) // returns System.NullReferenceException: Object reference not set to an instance of an object. - because x is null !!!
MessageBox.Show("true");
else
MessageBox.Show("false");
回答by Andrew
I've just been banging my head against a wall trying to solve a bug because I read this page and concluded there was no meaningful difference when in practice there is so I'll post this link here in case anyone else finds they get different results out of == and equals.
我只是一直在试图解决一个错误,因为我读了这个页面并得出结论,在实践中没有有意义的差异,所以我会在这里发布这个链接,以防其他人发现他们得到不同的结果出于 == 和等于。
Object == equality fails, but .Equals succeeds. Does this make sense?
Object == 相等失败,但 .Equals 成功。这有意义吗?
string a = "x";
string b = new String(new []{'x'});
Console.WriteLine("x == x " + (a == b));//True
Console.WriteLine("object x == x " + ((object)a == (object)b));//False
Console.WriteLine("x equals x " + (a.Equals(b)));//True
Console.WriteLine("object x equals x " + (((object)a).Equals((object)b)));//True
回答by Matthijs Wessels
I want to add that there is another difference. It is related to what Andrew posts.
我想补充一点,还有另一个区别。它与安德鲁发布的内容有关。
It is also related to a VERY annoying to find bug in our software. See the following simplified example (I also omitted the null check).
这也与在我们的软件中发现错误非常烦人有关。请参阅以下简化示例(我也省略了空检查)。
public const int SPECIAL_NUMBER = 213;
public bool IsSpecialNumberEntered(string numberTextBoxTextValue)
{
return numberTextBoxTextValue.Equals(SPECIAL_NUMBER)
}
This will compile and always return false
. While the following will give a compile error:
这将编译并始终返回false
。虽然以下将给出编译错误:
public const int SPECIAL_NUMBER = 213;
public bool IsSpecialNumberEntered(string numberTextBoxTextValue)
{
return (numberTextBoxTextValue == SPECIAL_NUMBER);
}
We have had to solve a similar problem where someone compared enums of different type using Equals
. You are going to read over this MANY times before realising it is the cause of the bug. Especially if the definition of SPECIAL_NUMBER
is not near the problem area.
我们不得不解决一个类似的问题,即有人使用Equals
. 在意识到它是错误的原因之前,您将多次阅读此内容。特别是如果 的定义SPECIAL_NUMBER
不在问题区域附近。
This is why I am really against the use of Equals in situations where is it not necessary. You lose a little bit of type-safety.
这就是为什么我真的反对在不必要的情况下使用 Equals。你失去了一点类型安全。
回答by vikas
There is practical difference between string.Equals
and ==
string.Equals
和之间存在实际差异==
bool result = false;
object obj = "String";
string str2 = "String";
string str3 = typeof(string).Name;
string str4 = "String";
object obj2 = str3;
// Comparision between object obj and string str2 -- Com 1
result = string.Equals(obj, str2);// true
result = String.ReferenceEquals(obj, str2); // true
result = (obj == str2);// true
// Comparision between object obj and string str3 -- Com 2
result = string.Equals(obj, str3);// true
result = String.ReferenceEquals(obj, str3); // false
result = (obj == str3);// false
// Comparision between object obj and string str4 -- Com 3
result = string.Equals(obj, str4);// true
result = String.ReferenceEquals(obj, str4); // true
result = (obj == str4);// true
// Comparision between string str2 and string str3 -- Com 4
result = string.Equals(str2, str3);// true
result = String.ReferenceEquals(str2, str3); // false
result = (str2 == str3);// true
// Comparision between string str2 and string str4 -- Com 5
result = string.Equals(str2, str4);// true
result = String.ReferenceEquals(str2, str4); // true
result = (str2 == str4);// true
// Comparision between string str3 and string str4 -- Com 6
result = string.Equals(str3, str4);// true
result = String.ReferenceEquals(str3, str4); // false
result = (str3 == str4);// true
// Comparision between object obj and object obj2 -- Com 7
result = String.Equals(obj, obj2);// true
result = String.ReferenceEquals(obj, obj2); // false
result = (obj == obj2);// false
Adding Watch
添加监视
obj "String" {1#} object {string}
str2 "String" {1#} string
str3 "String" {5#} string
str4 "String" {1#} string
obj2 "String" {5#} object {string}
Now look at {1#}
and {5#}
现在看看{1#}
和{5#}
obj
, str2
, str4
and obj2
references are same.
obj
, str2
,str4
和obj2
参考文献相同。
obj
and obj2
are object type
and others are string type
obj
并且obj2
是object type
和其他人string type
结论:
- com1: result = (obj == str2);// true
- compares
object
andstring
so performs a reference equality check - obj and str2 point to the same reference so the result is true
- compares
- com2: result = (obj == str3);// false
- compares
object
andstring
so performs a reference equality check - obj and str3 point to the different references so the result is false
- compares
- com3: result = (obj == str4);// true
- compares
object
andstring
so performs a reference equality check - obj and str4 point to the same reference so the result is true
- compares
- com4: result = (str2 == str3);// true
- compares
string
andstring
so performs a string value check - str2 and str3 are both "String" so the result is true
- compares
- com5: result = (str2 == str4);// true
- compares
string
andstring
so performs a string value check - str2 and str4 are both "String" so the result is true
- compares
- com6: result = (str3 == str4);// true
- compares
string
andstring
so performs a string value check - str3 and str4 are both "String" so the result is true
- compares
- com7: result = (obj == obj2);// false
?- compares
object
andobject
so performs a reference equality check ? ? ?- obj and obj2 point to the different references so the result is false
- com1: 结果 = (obj == str2);// 真
- 比较
object
并string
因此执行引用相等性检查 - obj 和 str2 指向同一个引用,所以结果为真
- 比较
- com2: 结果 = (obj == str3);// 假
- 比较
object
并string
因此执行引用相等性检查 - obj 和 str3 指向不同的引用,因此结果为 false
- 比较
- com3: 结果 = (obj == str4);// 真
- 比较
object
并string
因此执行引用相等性检查 - obj 和 str4 指向相同的引用,所以结果为真
- 比较
- com4: 结果 = (str2 == str3);// 真
- 比较
string
等string
执行字符串值检查 - str2 和 str3 都是“字符串”,所以结果为真
- 比较
- com5: 结果 = (str2 == str4);// 真
- 比较
string
等string
执行字符串值检查 - str2 和 str4 都是“字符串”,所以结果为真
- 比较
- com6: 结果 = (str3 == str4);// 真
- 比较
string
等string
执行字符串值检查 - str3 和 str4 都是“字符串”,所以结果为真
- 比较
- com7: result = (obj == obj2);// false ?- 比较
object
并object
执行引用相等性检查 ? ? ?- obj 和 obj2 指向不同的引用,所以结果为假
回答by Andrew Arnott
There is one subtle but very important differencebetween == and the String.Equals methods:
== 和 String.Equals 方法之间有一个微妙但非常重要的区别:
class Program
{
static void Main(string[] args)
{
CheckEquality("a", "a");
Console.WriteLine("----------");
CheckEquality("a", "ba".Substring(1));
}
static void CheckEquality<T>(T value1, T value2) where T : class
{
Console.WriteLine("value1: {0}", value1);
Console.WriteLine("value2: {0}", value2);
Console.WriteLine("value1 == value2: {0}", value1 == value2);
Console.WriteLine("value1.Equals(value2): {0}", value1.Equals(value2));
if (typeof(T).IsEquivalentTo(typeof(string)))
{
string string1 = (string)(object)value1;
string string2 = (string)(object)value2;
Console.WriteLine("string1 == string2: {0}", string1 == string2);
}
}
}
Produces this output:
产生这个输出:
value1: a value2: a value1 == value2: True value1.Equals(value2): True string1 == string2: True ---------- value1: a value2: a value1 == value2: False value1.Equals(value2): True string1 == string2: True
value1: a value2: a value1 == value2: True value1.Equals(value2): True string1 == string2: True ---------- value1: a value2: a value1 == value2: False value1.Equals(value2): True string1 == string2: True
You can see that the == operator is returning falseto two obviously equal strings. Why? Because the == operator in use in the generic method is resolved to be the op_equal method as defined by System.Object (the only guarantee of T the method has at compile time), which means that it's reference equality instead of value equality.
您可以看到 == 运算符对两个明显相等的字符串返回false。为什么?因为泛型方法中使用的 == 运算符被解析为 System.Object 定义的 op_equal 方法(该方法在编译时对 T 的唯一保证),这意味着它是引用相等而不是值相等。
When you have two values typed as System.String explicitly, then == has a value-equality semantic because the compiler resolves the == to System.String.op_equal instead of System.Object.op_equal.
当您有两个显式类型为 System.String 的值时,== 具有值相等语义,因为编译器将 == 解析为 System.String.op_equal 而不是 System.Object.op_equal。
So to play it safe, I almost always use String.Equals instead to that I always get the value equality semantics I want.
所以为了安全起见,我几乎总是使用 String.Equals 来代替我总是得到我想要的值相等语义。
And to avoid NullReferenceExceptions if one of the values is null, I always use the staticString.Equals method:
如果其中一个值为空,为了避免 NullReferenceExceptions,我总是使用静态String.Equals 方法:
bool true = String.Equals("a", "ba".Substring(1));