== 和 Equals() 之间的 C# 区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/814878/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:14:40  来源:igfitidea点击:

C# difference between == and Equals()

c#.netequals

提问by Drahcir

I have a condition in a silverlight application that compares 2 strings, for some reason when I use ==it returns falsewhile .Equals()returns true.

我在 Silverlight 应用程序中有一个比较 2 个字符串的条件,出于某种原因,当我使用==它时返回false.Equals()返回true

Here is the code:

这是代码:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

Any reason as to why this is happening?

关于为什么会发生这种情况的任何原因?

采纳答案by Mehrdad Afshari

When ==is used on an expression of type object, it'll resolve to System.Object.ReferenceEquals.

==用于 type 的表达式时object,它将解析为System.Object.ReferenceEquals

Equalsis just a virtualmethod and behaves as such, so the overridden version will be used (which, for stringtype compares the contents).

Equals只是一种virtual方法并且行为如此,因此将使用覆盖的版本(对于string类型比较内容)。

回答by BlueMonkMN

When comparing an object reference to a string (even if the object reference refers to a string), the special behavior of the ==operator specific to the string class is ignored.

将对象引用与字符串进行比较时(即使对象引用引用字符串),==特定于字符串类的运算符的特殊行为将被忽略。

Normally (when not dealing with strings, that is), Equalscompares values, while ==compares object references. If two objects you are comparing are referring to the same exact instance of an object, then both will return true, but if one has the same content and came from a different source (is a separate instance with the same data), only Equals will return true. However, as noted in the comments, string is a special case because it overrides the ==operator so that when dealing purely with string references (and not object references), only the values are compared even if they are separate instances. The following code illustrates the subtle differences in behaviors:

通常(即不处理字符串时),Equals比较,而==比较对象引用。如果您比较的两个对象指的是一个对象的同一个实例,则两者都将返回 true,但如果一个具有相同的内容并且来自不同的源(是具有相同数据的单独实例),则只有 Equals返回真。但是,正如注释中所指出的,字符串是一种特殊情况,因为它覆盖了==运算符,因此在纯粹处理字符串引用(而不是对象引用)时,即使它们是单独的实例,也只会比较值。以下代码说明了行为的细微差别:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

The output is:

输出是:

True True True
False True True
False False True

回答by JaredPar

==and .Equalsare both dependent upon the behavior defined in the actual type and the actual type at the call site. Both are just methods / operators which can be overridden on any type and given any behavior the author so desires. In my experience, I find it's common for people to implement .Equalson an object but neglect to implement operator ==. This means that .Equalswill actually measure the equality of the values while ==will measure whether or not they are the same reference.

==并且.Equals都取决于实际类型中定义的行为和调用站点的实际类型。两者都只是方法/运算符,可以在任何类型上覆盖并给出作者想要的任何行为。根据我的经验,我发现人们.Equals在对象上实现但忽略实现 operator是很常见的==。这意味着.Equals将实际测量值的相等性,同时==将测量它们是否是相同的引用。

When I'm working with a new type whose definition is in flux or writing generic algorithms, I find the best practice is the following

当我使用定义不断变化的新类型或编写泛型算法时,我发现最佳实践如下

  • If I want to compare references in C#, I use Object.ReferenceEqualsdirectly (not needed in the generic case)
  • If I want to compare values I use EqualityComparer<T>.Default
  • 如果我想比较 C# 中的引用,我Object.ReferenceEquals直接使用(一般情况下不需要)
  • 如果我想比较我使用的值 EqualityComparer<T>.Default

In some cases when I feel the usage of ==is ambiguous I will explicitly use Object.Referenceequals in the code to remove the ambiguity.

在某些情况下,当我觉得 的用法==有歧义时,我会Object.Reference在代码中明确使用equals 来消除歧义。

Eric Lippert recently did a blog post on the subject of why there are 2 methods of equality in the CLR. It's worth the read

Eric Lippert 最近发表了一篇关于为什么 CLR 中有 2 种相等方法的主题的博客文章。值得一读

回答by Mehmet Aras

I am a bit confused here. If the runtime type of Content is of type string, then both == and Equals should return true. However, since this does not appear to be the case, then runtime type of Content is not string and calling Equals on it is doing a referential equality and this explains why Equals("Energy Attack") fails. However, in the second case, the decision as to which overloaded == static operator should be called is made at compile time and this decision appears to be ==(string,string). this suggests to me that Content provides an implicit conversion to string.

我在这里有点困惑。如果 Content 的运行时类型是字符串类型,则 == 和 Equals 都应返回 true。但是,由于情况似乎并非如此,因此内容的运行时类型不是字符串,并且对其调用 Equals 是在执行引用相等,这解释了 Equals("Energy Attack") 失败的原因。然而,在第二种情况下,关于应该调用哪个重载 == 静态运算符的决定是在编译时做出的,这个决定似乎是 ==(string,string)。这向我表明 Content 提供了到字符串的隐式转换。

回答by MikeKulls

I would add that if you cast your object to a string then it will work correctly. This is why the compiler will give you a warning saying:

我要补充一点,如果您将对象转换为字符串,那么它将正常工作。这就是为什么编译器会给你一个警告说:

Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'string'

可能的意外参考比较;要进行值比较,请将左侧强制转换为“字符串”

回答by Bala

Adding one more point to the answer.

给答案补充一点。

.EqualsTo()method gives you provision to compare against culture and case sensitive.

.EqualsTo()方法为您提供了与文化和区分大小写进行比较的条件。

回答by kashif

== Operator

== 运算符

  1. If operands are Value Typesand their valuesare equal, it returns true else false.
  2. If operands are Reference Typeswith exception of string and both refer to the same instance(same object), it returns true else false.
  3. If operands are stringtype and their valuesare equal, it returns true else false.
  1. 如果操作数是值类型并且它们的相等,则返回 true 否则返回 false。
  2. 如果操作数是除字符串之外的引用类型并且都引用同一个实例(同一个对象),则返回 true 否则返回 false。
  3. 如果操作数是字符串类型并且它们的相等,则返回真,否则返回假。

.Equals

。等于

  1. If operands are Reference Types, it performs Reference Equalitythat is if both refer to the same instance(same object), it returns true else false.
  2. If Operands are Value Typesthen unlike == operator it checks for their typefirst and if their types are same it performs == operator else it returns false.
  1. 如果操作数是引用类型,则执行引用相等,即如果两者都引用同一个实例(同一个对象),则返回 true,否则返回 false。
  2. 如果操作数是值类型,则与 == 运算符不同,它首先检查它们的类型,如果它们的类型相同,则执行 == 运算符,否则返回 false。

回答by Colonel Panic

Firstly, there isa difference. For numbers

首先,有有差别。对于数字

> 2 == 2.0
True

> 2.Equals(2.0)
False

And for strings

而对于字符串

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

In both cases, ==behaves more usefully than .Equals

在这两种情况下,==表现都比.Equals

回答by supercat

The ==token in C# is used for two different equality-check operators. When the compiler encounters that token, it will check whether either of the types being compared has implemented an equality-operator overload for either the specific combination types being compared(*), or for a combination of types to which both types can be converted. If the compiler finds such an overload it will use it. Otherwise, if the two types are both reference types and they are not unrelated classes (either may be an interface, or they may be related classes), the compiler will regard ==as a reference-comparison operator. If neither condition applies, compilation will fail.

==C# 中的标记用于两个不同的相等检查运算符。当编译器遇到该标记时,它将检查被比较的任一类型是否已为被比较的特定组合类型 (*) 或两种类型都可以转换为的类型组合实现了相等运算符重载。如果编译器发现这样的重载,它将使用它。否则,如果这两种类型都是引用类型并且它们不是不相关的类(可能是接口,也可能是相关类),则编译器将==视为引用比较运算符。如果两个条件都不适用,编译将失败。

Note that some other languages use separate tokens for the two equality-check operators. In VB.NET, for example, the =token is used within expressions solely for the overloadable equality-check operator, and Isis used as a reference-test or null-test operator. An to use =on a type which does not override the equality-check operator will fail, as will attempting to use Isfor any purpose other than testing reference equality or nullity.

请注意,其他一些语言对两个相等检查运算符使用单独的标记。例如,在 VB.NET 中,=标记在表达式中仅用于可重载的相等检查运算符,并Is用作引用测试或空值测试运算符。=在不覆盖相等检查运算符的类型上使用将失败,尝试将其Is用于测试引用相等性或无效性以外的任何目的也会失败。

(*)Types generally only overload equality for comparison with themselves, but it may be useful for types to overload the equality operator for comparison with other particular types; for example, intcould have (and IMHO should have but didn't) defined an equality operators for comparison with float, so that 16777217 would not report itself equal to 16777216f. As it is, since no such operator is defined, C# will promote the intto float, rounding it to 16777216f before the equality-check operator sees it; that operator then sees two equal floating-point numbers and reports them as equal, unaware of the rounding that took place.

(*) 类型通常只重载相等以与自身进行比较,但对于类型来说,重载相等运算符以与其他特定类型进行比较可能很有用;例如,int可以(恕我直言应该有但没有)定义一个相等的运算符来与 进行比较float,这样 16777217 就不会报告自己等于 16777216f。实际上,由于没有定义这样的运算符,C# 将提升intto float,在相等检查运算符看到它之前将其四舍五入为 16777216f ;该运算符然后看到两个相等的浮点数并将它们报告为相等,不知道发生的舍入。

回答by user3440463

When we create any object there are two parts to the object one is the content and the other is reference to that content. ==compares both content and reference; equals()compares only content

当我们创建任何对象时,对象有两个部分,一个是内容,另一个是对该内容的引用。 ==比较内容和参考; equals()只比较内容

http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq

http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq