C#值类型、引用类型中的Equals和==的区别浅析

C#值类型、引用类型中的Equals和==的区别浅析

相关概念

在讨论 Equals== 的区别之前,我们先来了解一下 C# 中两种常见的数据类型:值类型和引用类型。

值类型

值类型指的是简单的数据类型,如 intdoublechar 等等。值类型的数据在赋值和传递时,始终是复制一份数据,而不是像引用类型那样复制一份指向数据的指针。

int a = 1;
int b = a;

以上代码中,第二行的赋值操作不会影响第一行的变量 a,因为 int 是一个值类型,所以 b 将完全复制 a 中的值。

引用类型

引用类型则是指向某个对象的引用,而不是该对象本身。常见的引用类型包括 string 和自定义的类、接口等等。引用类型的数据在赋值和传递时,实际上是复制了一份指向同一个对象的引用,而不是复制了一个新的对象。

string s1 = "hello";
string s2 = s1;

以上代码中,第二行的赋值操作将使 s2 引用与 s1 引用指向同一个 string 对象。如果修改了 s2 的值,则实际上也会修改 s1 对应的字符串。

Equals 和 == 的区别

值类型中的 Equals 和 ==

在值类型中,Equals== 的作用是类似的,都是用来比较值是否相等的。区别在于:

  • Equals 可以被重写,而 == 操作符不行
  • Equals 需要一个对象作为参数,而 == 操作符可以直接比较两个值类型的值
int a = 1;
int b = 2;
bool equal1 = a.Equals(b);  // false
bool equal2 = (a == b);     // false

// 重写 Equals 方法
struct MyStruct
{
    public int X;
    public int Y;

    public override bool Equals(object obj)
    {
        if (obj is MyStruct)
        {
            MyStruct other = (MyStruct)obj;
            return (this.X == other.X && this.Y == other.Y);
        }
        return false;
    }
}

MyStruct s1 = new MyStruct { X = 1, Y = 2 };
MyStruct s2 = new MyStruct { X = 1, Y = 2 };
bool equal3 = s1.Equals(s2);  // true
bool equal4 = (s1 == s2);     // false,因为 MyStruct 没有重载 == 操作符

引用类型中的 Equals 和 ==

在引用类型中,Equals== 的作用不一样了:

  • Equals 用于判断两个对象的值是否相等
  • == 用于判断两个对象的引用是否相等

换句话说,如果想比较引用类型的值是否相等,应该使用 Equals 方法;如果想比较两个引用类型的对象是否是同一个对象,应该使用 == 操作符。

string s1 = "hello";
string s2 = "HELLO".ToLower();
bool equal1 = s1.Equals(s2);  // true,因为两个字符串的值相等
bool equal2 = (s1 == s2);     // false,因为 s1 和 s2 引用的不是同一个字符串对象

示例

示例一:对象引用为 null

string s1 = null;
string s2 = null;
bool equal1 = s1.Equals(s2);  // 抛出 NullReferenceException 异常
bool equal2 = (s1 == s2);     // true

以上代码中,由于 s1s2 引用都为 null,因此使用 s1.Equals(s2) 方法时会抛出 NullReferenceException 异常。但是,s1 == s2 会返回 true,因为两个引用都是 null

示例二:自定义类重载 Equals 方法

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Person)
        {
            Person other = (Person)obj;
            return (this.Name == other.Name && this.Age == other.Age);
        }
        return false;
    }
}

Person p1 = new Person { Name = "Alice", Age = 25 };
Person p2 = new Person { Name = "Alice", Age = 25 };
bool equal1 = p1.Equals(p2);  // true
bool equal2 = (p1 == p2);     // false

以上代码中,自定义了一个 Person 类,并重载了它的 Equals 方法,用于比较两个 Person 对象的值是否相等。在比较 p1p2 时,通过 p1.Equals(p2) 方法可以正确地判断两个对象的值是否相等。但是,p1 == p2 操作符却会返回 false,因为 Person 类没有重载 == 操作符。如果需要使 == 操作符可以比较两个 Person 对象的值是否相等,还需要在 Person 类中定义相应的 == 操作符重载方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#值类型、引用类型中的Equals和==的区别浅析 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • jQuery获取地址栏参数插件(模仿C#)

    jQuery获取地址栏参数插件(模仿C#)是一个可以方便的获取URL参数的工具。下面是详细的攻略: 1. 插件的引入 首先需要在页面中引入jQuery库,然后才能引入该插件。可以使用以下代码: <script src="https://code.jquery.com/jquery-3.5.1.min.js"></scri…

    C# 2023年5月15日
    00
  • 深入理解c#多态

    深入理解C#多态的完整攻略 什么是多态? 在面向对象编程(OOP)中,多态是指同一个方法在不同情况下表现出现不同的行为。简单来说,就是同样的操作在不同的对象上可以有不同的实现。多态的概念是OOP中的三大特性之一,其它两个是封装和继承。 C#中的多态 C#中的多态性是通过虚方法(Virtual Methods)、抽象类和接口实现的。关键字virtual和ove…

    C# 2023年5月31日
    00
  • NetCore WebSocket即时通讯示例

    NetCore WebSocket即时通讯示例是一种使用ASP.NET Core SignalR实现WebSocket即时通讯的方法。本文将详细讲解NetCore WebSocket即时通讯示例的实现过程,包括环境搭建、代码实现、示例说明等。 环境搭建 在开始实现NetCore WebSocket即时通讯示例之前,我们需要先搭建好开发环境。具体来说,我们需要…

    C# 2023年5月16日
    00
  • 基于.net core微服务的另一种实现方法

    基于.NET Core微服务的另一种实现方法 微服务架构是一种流行的软件架构,它将应用程序拆分成多个小型服务,每个服务都可以独立部署、扩展和维护。在.NET Core中,可以使用多种方式实现微服务架构。本文将介绍一种基于.NET Core微服务的另一种实现方法,包括以下步骤: 创建微服务项目 实现微服务 部署微服务 1. 创建微服务项目 首先,我们需要创建一…

    C# 2023年5月15日
    00
  • C# 爬虫简单教程

    关于“C#爬虫简单教程”的完整攻略,可以分为以下几个步骤: 1. 确定需求和目标 在开始写爬虫之前,首先需要确定爬虫的目标和需求,例如要爬取哪些网站,获取哪些数据,以及存储数据的方式等等。在确定需求的基础上,就可以开始编写代码了。 2. 安装和准备开发环境 使用C#编写爬虫,需要安装.Net框架和Visual Studio开发环境。具体安装过程可以参考微软官…

    C# 2023年5月15日
    00
  • WinForm实现鼠标拖动控件跟随效果

    为了实现WinForm中的鼠标拖动控件跟随效果,我们需要使用下述步骤: 1. 获取鼠标位置 鼠标在界面上移动时,我们需要获取其当前位置。可以通过下面的代码来获取: private void panel1_MouseMove(object sender, MouseEventArgs e) { Point point = Control.MousePositi…

    C# 2023年6月1日
    00
  • 解析.netcore项目中IStartupFilter使用教程

    IStartupFilter是.NET Core中的一个接口,用于在应用程序启动时执行一些额外的操作。在本攻略中,我们将详细讲解如何解析.NET Core项目中的IStartupFilter使用教程。 创建StartupFilter类:首先,我们需要创建一个名为StartupFilter的类,并实现IStartupFilter接口。我们可以在.NET Cor…

    C# 2023年5月16日
    00
  • C# wpf解决Popup弹出位置异常问题解决

    在WPF中,我们可以通过Popup弹出一个窗口,但是由于窗口的弹出位置可能会和我们期望的不一样,而且有时候在某些屏幕分辨率下表现得更为明显。在这种情况下,我们需要进行调整以确保Popup窗口出现在我们期望的位置。下面是解决这个问题的方法: 1. 设置PlacementMode属性 在Popup控件中,可以通过设置PlacementMode属性来控制Popup…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部