65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的 == 与 Equals

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (12投票s)

2016年7月12日

CPOL

5分钟阅读

viewsIcon

60924

在本文中,我们将讨论 C# 中 == 和 Equals 之间的区别。

目录

引言
要点 1:- 基于相等性进行比较


要点 2:- 编译时 vs 运行时
要点 3:- NULL 情况
何时使用哪个:- 技术比较 vs 语义比较
全景

 

引言

为了比较变量之间的相等性,C# 提供了两种比较方式:“==”和一个重载方法“equals()”。大多数开发人员使用“==”,而“Equals”则很少被讨论。

因此,在这篇简短的笔记中,我们将讨论它们之间的区别以及何时使用哪个。

要点 1:- 基于相等性进行比较

回答“使用‘==’和‘Equals()’进行相等性比较没有区别,除了比较‘字符串’时。

通用比较规则:- 无论何时比较变量,它们要么是值类型,要么是引用类型。比较值类型时,是基于“内容”进行比较;比较引用类型时,是基于“引用”(内存地址)而不是“内容”进行比较。

上述规则同时被“==”和“Equals”所遵循。

场景 1:- 值类型比较

当您使用“==”或“Equals”比较值类型/原始数据类型(int、double 等)时,始终基于内容。在下面的代码中,您可以看到两种比较方法都显示为“true”。

int i = 10;
int y = 10;
Console.WriteLine(i == y); // true
Console.WriteLine(i.Equals(y)); // true

场景 2:- 引用类型比较

现在,当您比较对象时,它们是基于引用(内部内存指针)进行比较的。下面 obj 和 obj1 的比较,无论是通过“==”还是“Equals”,都将是 false。因此,在下面的代码中,即使两个对象的属性名称都为“Shiv”,仍然显示不相等。因为比较是基于内部内存引用,而“obj”和“obj1”的内存引用是不同的。

Customerobj = newCustomer();
obj.Name = "Shiv";
Customer obj1 = newCustomer();
obj1.Name = "Shiv";
Console.WriteLine(obj == obj1); // false
Console.WriteLine(obj.Equals(obj1)); // false

但下面的代码将显示 true,因为指针指向同一个对象。

Customerobj = newCustomer();
obj.Name = "Shiv";
Customer obj1 = obj;
Console.WriteLine(obj == obj1); // true
Console.WriteLine(obj.Equals(obj1)); // true

场景 3:- 字符串比较、驻留和对象类型转换

现在字符串是不可变对象或引用类型,因此它们应该使用引用类型的规则进行检查。换句话说,在下面的场景中,当我们为“str”赋值时,它会创建一个字符串对象并在堆中存储“test”。当您现在赋值“str1”时,它是一个不同的对象,所以它应该是一个不同的实例。

但是看值,它是相同的。因此 C# 字符串遵循驻留规则。换句话说,如果内容相同,“str”和“str1”指向相同的内存位置和数据。因此,“==”和“Equals”都将为 true。

objectstr = "test";
object str1 = "test";
Console.WriteLine(str==str1);
Console.WriteLine(str.Equals(str1));

但是现在看看下面的代码,我们显式地创建了具有相同值的独立字符串对象。我们强制覆盖了字符串的驻留行为。在下面的代码中,“==”将返回 false,即使内容相同,而“Equals”将返回 true。这是相等性行为不同的地方之一。

objectstr = newstring(newchar[] { 't', 'e', 's', 't' });
object str1 = newstring(newchar[] { 't', 'e', 's', 't' });
Console.WriteLine(str==str1); // false
Console.WriteLine(str.Equals(str1));  // true

要点 2:- 编译时 vs 运行时

使它们不同的下一个要点是类型检查何时发生。“==”在编译时进行类型检查,而“Equals”更是在运行时进行。“==”会显示警告消息,并带有绿色符号,表明您正在比较不同类型的对象,并且可能会出现问题。“Equals”不会显示任何此类警告。

要点 3:- NULL 情况

“==”可以处理 null,但“Equals”在比较 NULL 值时会崩溃,请看下面的截图。

何时使用哪个:- 技术比较 vs 语义比较

“==”是 C# 运算符,而“Equals”是多态方法。因此,换句话说,“==”是一种语言特性,而“Equals”是一种面向对象编程特性,遵循多态性。

现在比较有两种类型:一种纯粹基于内容和引用,也就是说,计算机进行的比较;另一种是基于语义。语义是指事物的实际含义。例如,1 与 70 在数值上(技术上)<>,但在现实世界中,1 美元在语义上等于 70 卢比。

更多示例:-

  • 技术上:- 1 等于 1。
  • 语义上:- 1 美元不等于 1 卢比。
  • 技术上:- “Destination”一词不等于“Last Stop”。
  • 语义上:- “Destination”与“Last Stop”的意思相同。

因此,技术比较是基于计算机的,而语义比较是基于业务的,或者我们可以说存在某种领域的规则用于比较。

那么,现在何时使用“==”以及何时使用“Equals”:-

  • 如果您正在寻找技术比较,请使用“==”,而且在大多数情况下,“==”就足够了,因为开发人员大多进行技术比较。
  • 如果您进行语义比较,那么您需要重写“equals”方法,加入语义比较逻辑,并在比较时使用“equals”方法。

全景

因此,如果我们列出所有要点,最终的结论如下表所示。

    ==   Equals
用法 基于技术 基于语义
值类型 基于内容的比较 基于内容的比较
对象 基于引用的比较 基于引用的比较
字符串 基于内容的比较 基于内容的比较
无驻留的字符串 基于引用的比较 基于内容的比较
类型检查 编译时 运行时
Nulls 工作 可能崩溃

观看以下实际视频,了解 == 和 .Equals 之间的区别:-

进一步阅读,请观看下面的面试准备视频和分步视频系列。

© . All rights reserved.