C#中相等比较 == 和 Equal函数 对比

1.== 运算符

== 是一个运算符,用于比较两个值是否相等。对于值类型(如 intfloatdouble 等),== 直接比较两个值是否相同。对于引用类型(如类和数组),== 比较两个引用是否指向内存中的同一个对象。

2.Equal函数

C#中所有类型(自定义的也一样)都继承自System.Object类,因此所有类型都有Equal这个比较方法,Equal一般会来自两个地方

第一个地方

public virtual bool Equals(object obj)
//自己可以重写的噢

这是从 System.Object 继承而来的方法,它接受一个 object 类型的参数。默认情况下,这个方法执行引用相等性检查,即它检查两个对象是否引用同一个对象实例。

第二个地方

public bool Equals(T other)

这是一个泛型重载,它接受一个与当前对象类型相同的参数。这个重载通常在实现了 IEquatable<T> 接口的类中被重写,用于执行值相等性检查。

如Int类型的:(override是重写,这个函数Equals(object obj)它还可以重写的)

对于引用类型,Equals(object obj) 默认比较的是引用,即检查两个对象是否是同一个实例。对于值类型,它比较的是值。

3.string、结构体struct比较

对于 string、 结构体struct类型,使用 == 运算符和 Equals 方法都是进行值比较,它们的行为是一致的。

4.不同

==运算符可以处理null,而Object.Equals 操作变量为null时会报错,如下

Ap re = null;
Ap res = new Ap();if(re.Equals(res))
{Console.WriteLine("相同");
}未经处理的异常:  System.NullReferenceException: 未将对象引用设置到对象的实例。

因此,使用Equals比较时请养成好习惯,记得判空

Ap re = null;
Ap res = new Ap();if(re != null)
{if(re.Equals(res)){Console.WriteLine("相同");}
}

参考:

比较 .NET 中的字符串 - .NET | Microsoft Learn

C# 中 == 和 .Equals() 之间的区别 - 误会馋 - 博客园(强烈推荐一读

纠错 1

int x = 2;
int y = 2;Console.WriteLine(x == y); //True
Console.WriteLine(x.Equals(y)); //TrueConsole.WriteLine(x == 2.0); //True
Console.WriteLine(x.Equals(2.0)); //False

Console.WriteLine(x == 2.0); //True

这里 == 操作符比较 int 类型的 x 和 double 类型的字面量 2.0。在C#中,int 类型可以隐式转换为 double 类型,这里发生了隐式转换,因此 2 被转换为 2.0,然后比较这两个值是否相等,结果是 True

Console.WriteLine(x.Equals(2.0)); //False

这里 Equals() 方法的行为与 == 操作符不同。Equals() 方法在没有被重写的情况下,对于 int 类型的 x 和 double 类型的 2.0,会返回 False,因为 Equals() 方法默认比较的是引用类型的引用是否相等,而 int 和 double 是不同的类型,它们在内存中的存储和表示也不同。即使它们的数值相同,Equals() 方法也会因为类型不匹配而返回 False。

如图可以看到编译器这里提示调用的函数,前一个Equal参数是同类型的int,这里的Equal参数类型时object

误区 2

在 C# 中,如果字符串的内容相同,那么认定它们指向相同的内存位置,这里是很多人容易犯错的误区,认为出现的字符串都是同一个对象,即堆区同一个地址;大部分情况是,因为string 类型在C#中有一个特殊的内部机制,称为字符串内部缓存。对于字面量字符串或者在编译时已知的字符串,编译器会尝试重用相同的字符串对象,这意味着即使它们在代码中被多次声明,它们实际上可能指向同一个对象。

有同学可能对字面量不理解,字面量是直接在代码中给出的值,而不是通过变量名或计算得到的

"ni hao"        //这是字面量,直接展示的10        //也是字面量、int a = 9;//a是变量,9是字面量

因此会有如下的代码对比

    public class Ap{public string a;}Ap ap1 = new Ap();ap1.a = "we";Ap ap2 = new Ap();ap2.a = "we";Console.WriteLine(ap1.a == ap2.a);//TrueConsole.WriteLine(ap1.a.Equals(ap2.a));//Truestring str1 = "Compare";string str2 = "Compare";Console.WriteLine(str1 == str2);//TrueConsole.WriteLine(str1.CompareTo(str2));//0Console.WriteLine(String.Compare(str1, str2));//0Console.WriteLine(str1.Equals(str2));//TrueConsole.WriteLine(String.Equals(str1, str2));//TrueConsole.WriteLine(Object.ReferenceEquals(str1, str2));//True

字面量的字符串都是相同的,因为引用了同一个地址,但是这并不适用于通过 new 关键字显式创建的字符串对象,因为显式创建的字符串对象总是不同的实例。

如下:

object str1 = new string(new char[] { 't', 'u', 't', 'o', 'r', 'i', 'a', 'l' });object str2 = new string(new char[] { 't', 'u', 't', 'o', 'r', 'i', 'a', 'l' });Console.WriteLine(str1 == str2);  //FalseConsole.WriteLine(str1.Equals(str2));  //Truestring str3 = new string(new char[] { 't', 'u', 't', 'o', 'r', 'i', 'a', 'l' });string str4 = new string(new char[] { 't', 'u', 't', 'o', 'r', 'i', 'a', 'l' });Console.WriteLine(str3 == str4);  //TrueConsole.WriteLine(str3.Equals(str4));  //True

Console.WriteLine(str1 == str2); //False

这里使用 == 操作符比较 str1 和 str2。由于 str1 和 str2 是通过 new string(new char[] {...}) 创建的两个不同的对象实例,即使它们的内容相同,它们在内存中的地址也是不同的。因此,== 操作符返回 False,因为它比较的是对象的引用。

Console.WriteLine(str1.Equals(str2)); //True

Equals 方法在 string 类型中被重写,所以父类object对象调用的是子类string重写后的String.Equals(object obj)方法,该方法比较的同样是内容而非引用

我们之前说过无论是==还是Equal在比较字符串时总是值比较,看到str3和str4比较,因此值相等自然就相等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891251.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 处理base64文件上传

场景&#xff1a; 在系统内有一个类似于公告的模块&#xff0c;如果里面添加的文章不是选择富文本上传图片的方式&#xff0c;而是选择复制别的文章直接粘贴到系统内的富文本&#xff0c;里面的图片就不会是url&#xff0c;而是图片的base64格式&#xff0c;这样会导致数据库存…

【行业发展报告】2024大数据与智能化行业发展浅析

回首 2024&#xff0c;大数据智能化浪潮汹涌。海量数据宛如繁星&#xff0c;在智能算法的苍穹下汇聚、碰撞&#xff0c;释放出洞察市场与用户的强大能量&#xff0c;精准勾勒出商业新航线。我们精心雕琢技术架构&#xff0c;从数据存储的坚固基石到处理分析的高效引擎&#xff…

项目基本配置

总说 本节主要记录修改配置文件、连接mysql数据库、git连接 一、配置文件的修改 1.1 配置pom.xml 由于我们要连接mysql数据库&#xff0c;需要在pom.xml中添加相关依赖 这里给出一个网站&#xff0c;可以找到各种依赖Maven Repository: Search/Browse/Explore 添加一个my…

【YOLOv3】源码(train.py)

概述 主要模块分析 参数解析与初始化 功能&#xff1a;解析命令行参数&#xff0c;设置训练配置项目经理制定详细的施工计划和资源分配日志记录与监控 功能&#xff1a;初始化日志记录器&#xff0c;配置监控系统项目经理使用监控和记录工具&#xff0c;实时跟踪施工进度和质量…

【Vim Masterclass 笔记02】第3章:Vim 核心知识 + L08:Vim 核心浏览命令 + L09:Vim 核心浏览命令同步练习

文章目录 Section 3&#xff1a;Vim Essentials&#xff08;Vim 核心知识&#xff09;S03L08 Essential Navigation Commands1 光标的上下左右移动2 上 / 下翻页3 基于单词前移4 基于单词后移5 重新定位视图中的文本&#xff08;页面重绘&#xff09;6 定位到所在行的行首7 光标…

基础数据结构--二叉树

一、二叉树的定义 二叉树是 n( n > 0 ) 个结点组成的有限集合&#xff0c;这个集合要么是空集&#xff08;当 n 等于 0 时&#xff09;&#xff0c;要么是由一个根结点和两棵互不相交的二叉树组成。其中这两棵互不相交的二叉树被称为根结点的左子树和右子树。 如图所示&am…

力扣-数据结构-7【算法学习day.78】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…

Android着色器SweepGradient渐变圆环,Kotlin

Android着色器SweepGradient渐变圆环&#xff0c;Kotlin import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.SweepGradient import android…

QT---------GUI程序设计基础

代码UI化设计&#xff08;QT&#xff09; 实例功能概述 假设我们要创建一个简单的计算器应用程序。该应用程序具有以下功能&#xff1a; 包含数字按钮&#xff08;0-9&#xff09;、操作符按钮&#xff08;、-、*、/&#xff09;、等于按钮&#xff08;&#xff09;和清除按…

torch.nn.functional的用法

文章目录 介绍激活函数示例 损失函数示例 卷积操作示例 池化示例 归一化操作示例 Dropout示例 torch.nn.functional 与 torch.nn 的区别 介绍 torch.nn.functional 是 PyTorch 中的一个模块&#xff0c;提供了许多函数式的神经网络操作&#xff0c;包括激活函数、损失函数、卷…

关于Nginx

1.Nginx的配置 proxy_pass http: 当你需要将请求分发到多个后端服务器时&#xff0c;需要实现负载均衡功能&#xff0c;可以使用upstream指令定义一组服务器&#xff0c;并在proxy_pass中引用这个服务组名称。。如果不需要负载均衡&#xff0c;只需要将请求转发到单一的后端…

redis用途都有哪些

Redis&#xff0c;作为一个开源的高性能键值对数据库&#xff0c;其用途广泛且功能强大。 1. 缓存&#xff08;Caching&#xff09;&#xff1a; • Redis常被用作缓存层&#xff0c;存储那些频繁访问但不易改变的数据&#xff0c;如用户会话、商品详情等。 • 通过将这些数据存…

Gemma2 2B 模型的model.safetensors.index.json文件解析

Gemma2 2B 模型的 model.safetensors.index.json 文件解析 在使用 Gemma2 2B 模型或其他大型预训练模型时&#xff0c;model.safetensors.index.json 文件起到了索引的作用&#xff0c;它帮助我们了解模型的结构、参数存储方式以及如何加载模型的具体权重。本博客将深入解析该…

JSON结构快捷转XML结构API集成指南

JSON结构快捷转XML结构API集成指南 引言 在当今的软件开发世界中&#xff0c;数据交换格式的选择对于系统的互操作性和效率至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是两种广泛使用的数据表…

期权懂|期权入门知识:开通50ETF期权需要什么条件?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 开通50ETF期权需要什么条件&#xff1f; 一、基本资格要求 &#xff08;1&#xff09;年龄限制&#xff1a;投资者必须年满18周岁&#xff0c;具备完全民事行为能力。 &#…

实景三维点云处理专业软件ArcGIS根据DSM生成地表点云集

常见的实景三维处理软件及其特色功能如下&#xff1a; 一、专业实景三维建模软件 Agisoft Metashape 高精度建模&#xff1a;能够生成高精度的三维模型&#xff0c;精度可以达到厘米级甚至毫米级&#xff0c;适用于需要详细测量和分析的项目&#xff0c;如文物保护和建筑测量。…

实战指南:Shiro、CAS打造完美单点登录体验

引言 想象一下&#xff0c;在日常工作中&#xff0c;我们经常需要进行系统认证和授权。当用户尝试登录一个网站时&#xff0c;他们需要提供用户名和密码&#xff0c;网站会检查这些信息&#xff0c;确认用户是谁。这就是认证的过程。 一旦用户被认证&#xff0c;他们可能会尝…

cuda-cuDnn

cuda sudo /bin/sh cuda_11.7.0_515.43.04_linux.run cudnn cuDNN Archive | NVIDIA Developer Linux 系统 CUDA 多版本共存以及切换 – 颢天 安装cuda # 如果已经安装过驱动&#xff0c;驱动不需要再安装&#xff0c;取消勾选 安装cuDNN&#xff0c;cuda-cuDNN对应关系见…

QComboBox中使用树形控件进行选择

事情是这样的&#xff0c;要在一个ComboBox中通过树形结构进行内容的选择。 默认的QComboBox展开是下拉的列表。因此需要定制一下。 效果就是这样的 实现上面效果的核心代码就是下面这样的 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { treenew…

【网络协议】路由信息协议 (RIP)

未经许可&#xff0c;不得转载。 路由信息协议&#xff08;Routing Information Protocol&#xff0c;简称 RIP&#xff09;是一种使用跳数&#xff08;hop count&#xff09;作为路由度量标准的路由协议&#xff0c;用于确定源网络和目标网络之间的最佳路径。 文章目录 什么是…