15

在 c# 中,当您在两个对象上与“==”运算符进行比较时,在后台究竟会发生什么?它只是比较地址吗?还是类似于 Equals() 或 CompareTo() ?

PS:java中的“==”操作符呢?它的行为是否相同?

4

6 回答 6

24

我所知道的:

  • 它按值(相等)比较值类型
  • 它按引用(身份)比较引用类型
  • 除非 == 运算符重载,否则它会调用该运算符。

Equals 在对象中实现,也可以被覆盖。Object 中的默认实现对引用类型执行引用比较。所以默认情况下,Equals 和 == 做同样的事情。

我认为在 java 中你不能重载 == 操作符。但是我的 Java 知识已经过时了。

编辑: 请注意,==运算符是静态方法。它在编译时绑定,基于变量或字段的类型。Equals是基于实际运行时类型在运行时找到的虚拟方法。

于 2009-04-30T09:06:15.457 回答
9

作为Stefan 出色答案的扩展- 另一个例外是操作数是否涉及Nullable<T>- 在这种情况下,“提升”运算符适用(ECMA 334v4 中的 14.2.7):

对于等式运算符 == !=

如果操作数类型都是不可为空的值类型并且结果类型是 bool,则存在运算符的提升形式。提升的形式是通过添加单个 ? 每个操作数类型的修饰符。提升的运算符认为两个空值相等,一个空值不等于任何非空值。如果两个操作数都不为空,则提升的运算符解开操作数并应用底层运算符来生成 bool 结果。

这意味着:因为(比如说)之间有一个相等运算符:

int i = ..., j = ...;
bool eq = i == j;

因此有一个形式的隐式运算符(虽然做的不同):

int? i = ..., j = ...;
bool eq;
if(i.HasValue) {
    if(j.HasValue) { // both have values; compare
       eq = i.GetValueOrDefault() == j.GetValueOrDefault();
    } else { // one null; always false
       eq = false;
    }
} else { // true if both null, else false
    eq = !j.HasValue;
}
于 2009-04-30T09:18:28.563 回答
4

来自 MSDN

对于预定义的值类型,相等运算符 (==) 如果其操作数的值相等则返回 true,否则返回 false。对于字符串以外的引用类型,== 如果它的两个操作数引用同一个对象,则返回 true。对于字符串类型,== 比较字符串的值。

于 2009-04-30T09:06:56.220 回答
3

不... == 运算符在 java 和 c# 中的行为并不总是相同。

例如字符串;Java == 确实比较了字符串对象的引用...(如果您使用原始类型, == 在 java 中比较值)。这就是为什么

// returns FALSE in JAVA
(new String("test") == "test") 

在java中不会返回true...

相比之下,在 C# 中, == 运算符在字符串上的行为确实不同。例如,它会在以下情况下返回 true:

// returns TRUE in C#
(new String("test".ToCharArray()) == "test") 
于 2009-04-30T09:07:22.037 回答
1

它的作用取决于上下文。

http://en.csharp-online.net/ECMA-334:_14.9_Relational_and_type-testing_operators

于 2009-04-30T09:06:43.113 回答
0

== 运算符的行为取决于您应用它的变量的声明方式(不是对象的类,我将添加一个示例)。

对于值类型,它将比较它们的值。

对于引用类型,如果 a 与 b 是同一个对象,则 a == b 返回 true,除非 == 运算符被重载。没有像其他人所说的那样被覆盖,你不能在 c# 中覆盖运算符,因为它们不是虚拟的。

object obj_a, obj_b; string str_a, str_b;

        str_a = "ABC";
        str_b = new string("ABC".ToCharArray());
        obj_a = str_a;
        obj_b = str_b;

        Console.WriteLine("str_a == str_b = {0}", str_a == str_b); // in string == operator is overloaded
        Console.WriteLine("str_a.Equals(str_b) = {0}", str_a.Equals(str_b)); // string overrides Object.Euqals
        Console.WriteLine("obj_a == obj_b = {0}", obj_a == obj_b); // in object == operator is not overloaded
        Console.WriteLine("obj_a.Equals(obj_b) = {0}", obj_a.Equals(obj_b)); // Object.Equesl is virtual and overridden method from string will be executed.
        Console.ReadKey();

该程序的输出是

str_a == str_b = 真
str_a.Equals(str_b) = True
obj_a == obj_b = 假
obj_a.Equals(obj_b) = True

于 2009-08-17T15:10:55.333 回答