声明:本篇博客翻译自:https://www.codeproject.com/Articles/1111680/equalsequals-VS-Equals-in-Csharp

由于水平(技术水平+英语理解能力)有限/不足,肯定会有所疏漏/错误,请及时指正。

介绍:

在C#中,可以使用“==”和一个可重载的"Equals()"方法来对变量进行比较。但是很多开发者并不知道两者之间的区别。在这篇博客中将讨论两者之间的区别和两者的使用场景。"=="和"Equals()"比较没有区别除了在做string的比较时。

比较规则:C#中的比较无非是对值类型和引用类型进行比较。当对值类型进行比较时,比较的是值类型的“内容”;当对引用类型进行比较时,比较的是对象的引用是否相同(内存地址)而不是“内容”。上述规则对"=="和"Equals()"均适用。

场景一:值类型比较

当对值类型(int, double, byte etc)进行比较时, "=="和"Equals()"都是基于值类型的内容比较。当值类型的内容相同,则两者相等。

Console.WriteLine("Value Type Compare...");
int i = ;
int y = ;
Console.WriteLine(i == y); // true
Console.WriteLine(i.Equals(y)); // true

场景二:引用类型比较

当对引用类型(object, interface)进行比较时,比较的是引用(内存地址)是否相同,下面代码中obj1和obj2使用"=="和“Equals”进行比较,结果为:false.尽管两个对象的内容一样的。但是内容地址不一样。

class Customer
{
public string Name { get; set; }
} Customer obj1 = new Customer();
obj1.Name = "Jimmy-Yang"; Customer obj2 = new Customer();
obj2.Name = "Jimmy-Yang"; Console.WriteLine(obj1 == obj2); // false
Console.WriteLine(obj1.Equals(obj2)); // false

如果obj1与obj2指向同一个引用(内存地址)。

Customer obj1 = new Customer();
obj1.Name = "Jimmy-Yang"; Customer obj2 = obj1; Console.WriteLine(obj1 == obj2); // true
Console.WriteLine(obj1.Equals(obj2)); // true

场景三:string比较

string类型是引用类型,那么下面代码中"str"创建一个string对象,并且在堆内存块上存储"test"字符。当创建str1后,虽然存储的内容一样,但是应该存储在不同的内存区域。

object str = "test";
object str1 = "test";
Console.WriteLine(str == str1); // true
Console.WriteLine(str.Equals(str1)); // ture

执行结果发现str与str1是相等的。这是为什么呢?
注意:C#的string类型遵循一条内部的规则。如果str与str1的内容相同,则两者指向系统的的内存地址。因此“==”和"Equals"会返回true。

但是注意下面的代码,我们创建了一个单独对象,然后赋值给string类型。此时“==”比较将返回false,Equals()将返回true。这是两者一个不同的地方。

object str = new string(new char[] { 't', 'e', 's', 't' });
object str1 = new string(new char[] { 't', 'e', 's', 't' });
Console.WriteLine(str == str1); // false
Console.WriteLine(str.Equals(str1)); // true

场景四:编译时VS运行时

两者之间在做类型检查时的区别。==在编译时做类型检查;Equals()在运行时做类型检查。请看下面的代码,在“==”会有一个警告信息。

场景五:NULL

当比较的对象为null时,“==”不会抛出异常,"Equals()"比较null对象时,会直接crash。

使用场景

"=="是C#提供的一个运算符,“Equals()”是基类提供的一个虚方法,可以在子类中继承,并编写自身比较逻辑。换句话说,“==”是一个C#的一个特性,而Equals是OOP的一个特性。两者的区别一个基于单纯的内容和引用(内存地址)比较。另一种是基于语义(Semantics, 此处我翻译成语义,其实更确切的应该是对象之间的含义)上的比较。例如:1 <> 10 (从技术层面上讲),但是现实生活中,1元=10角,此时1=10在含义上。

  • 如果单纯从技术层面上比较请使用“==”;
  • 如果从语义上比较(例如:1元=10角),你需要使用Equals方法并提供合适的比较逻辑。

总结

请看下面的表格:

    ==   Equals
Usage Technical based Semantic based
Value types Content based Comparison Content based Comparison
Objects Reference based Comparison Reference based Comparison
String  Content based Comparison Content based Comparison
String with no interning Reference based Comparison Content based Comparison
Type checking Compile time Run time
Nulls Works  Can crash

[C#] == VS Equals的更多相关文章

  1. equals变量在前面或者在后面有什么区别吗?这是一个坑点

    我就不废话那么多,直接上代码: package sf.com.mainTest; public class Test { public static void main(String[] args) ...

  2. How to implement equals() and hashCode() methods in Java[reproduced]

    Part I:equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and ...

  3. 【特种兵系列】String中的==和equals()

    1. 小样示例 public static void main(String[] args) { String a = "a" + "b" + 123; Str ...

  4. (转)浅谈Java中的equals和==

    原文地址: http://www.cnblogs.com/dolphin0520/p/3592500.html 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new S ...

  5. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  6. List<T>Find方法,FindAll方法,Contains方法,Equals方法

    假如传入的T是一个类, List<MessageInfos> MessageInfos = new List<MessageInfos>(); MessageInfos= Me ...

  7. 让代码重构渐行渐远系列(3)——string.Equals取代直接比较与非比较

    重构背景及原因 最近由于项目组的人员在不断扩充,导致项目中代码风格各异,大有百花齐放甚至怒放之势.考虑到团队的生存与发展,经过众人多次舌战之后,最终决定项目组根据业务分成几个小分队,以加强团队管理与提 ...

  8. [java] 更好的书写equals方法-汇率换算器的实现(4)

    [java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]>   [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...

  9. Equals和ReferenceEquals

    稍微分析下一下两个方法的区别: public static bool Equals(object objA, object objB); public static bool ReferenceEqu ...

  10. 【原创】Java和C#下String类型中的==和equals的原理与区别

    一.Java下 1.几个例子 public static void main(String[] arge) { String str1 = new String("1234"); ...

随机推荐

  1. ACdream区域赛指导赛之手速赛系列(2)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/DaiHaoC83E15/article/details/26187183        回到作案现场 ...

  2. IT项目管理的十六个字心得体会

    目标驱动,系统思维,风险意识,数据量化 凡事预则立,不预则废.如果你不知道要到哪里?给你一张地图也没有用.目标驱动首先要有最基本的计划管理和时间管理能力.对于一个项目,我们过程中做的所有工作都是为了要 ...

  3. maven库 mvn依赖

    http://maven.outofmemory.cn/ http://mvnrepository.com/ 先执行 mvn clean  然后执行  mvn 命令 如:mvn  compile  . ...

  4. VB中上传下载文件到SQL数据库

    VB中上传下载文件到SQL数据库 编写人:左丘文 2015-4-11 近期在修改一个VB编写的系统时,想给画面增加一个上传文件到数据库,并可以下载查看的功能,今天在这里,我想与大家一起分享代码,在此做 ...

  5. python学习日志

    马上就中秋节,想着再学点新的知识,本来想去继续研究前端知识来着,但是内个烦人的样式css还有js搞的有点脑壳头,以后就主学后端吧,要去死了前端这条心了? 那么寻寻觅觅就入坑最近几年大热的python吧 ...

  6. 黄聪:VS2010启动程序提示文件加载 使用 简体中文(GB2312)编码加载文件解决办法

    vs2010 错误提示框:文件加载 使用 简体中文(GB2312)编码加载文件C:\Users\Administrator\AppData\Local\Temp\nxhgjasi.5au \Temp\ ...

  7. pythonNet08

    线程通信 通信方法:多个线程共用进程空间,所以进程的全局变量对进程内线程均可见.线程往往使用全局变量进行通信 注意事项:线程间使用全局变量进行通信,全局变量为共享资源,往往需要同步互斥机制 线程的同步 ...

  8. buffer cache —— buffer busy waits/read by other session

    oracle提供非常精确.有效的row level lock机制,多个用户同时修改数据时,为了保护数据,以块为单位挂起锁的情况不会发生.但这不太正确.以块为单位的锁虽然不存在,但正因为oracle I ...

  9. Asp.netMVC中地址后缀使用.html,jsp等404错误解决

    asp.net mvc 默认的地址路径url都是没有后缀的比如 www.a.com/aa/bb 等 如果要是www.a.com/aa/bb.html需要专门写路由. 根据我之前的经验,mvc的路由是相 ...

  10. python中tornado的第一个例子

    1  先安装tornado pip install tornado 2 新建tor.py 记住不能建立 tornado.py 这样的名字  不然会报错 ImportError: No module n ...