C# 中的 == 与 Equals






4.96/5 (12投票s)
在本文中,我们将讨论 C# 中 == 和 Equals 之间的区别。
目录
要点 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 之间的区别:-
进一步阅读,请观看下面的面试准备视频和分步视频系列。