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日

相关文章

  • C#标识符的使用小结

    我将详细讲解 “C#标识符的使用小结”: 什么是标识符? 在C#编程语言中,标识符是用来表示各种元素名称(如变量、方法、命名空间等)的一个字符序列。合法的标识符必须符合以下规则: 标识符由字母、数字或下划线(_)组成 第一个字符必须是字母或下划线 标识符不能与C#语言的关键字(如if、for等)相同 标识符区分大小写 命名规范 在使用标识符时应遵循以下规范:…

    C# 2023年5月31日
    00
  • ASP.net中获取客户端参数操作系统信息

    获取客户端参数操作系统信息对于一些网站运营来说可能是很有用的信息,比如针对不同操作系统的用户可以进行不同的推荐或者展示。在ASP.net中获取客户端参数操作系统信息可以通过以下步骤实现: 在 ASP.net 页面的 header 部分添加以下代码块: <script type="text/javascript"> functi…

    C# 2023年6月3日
    00
  • 解析ASP.NET Core中Options模式的使用及其源码

    解析ASP.NET Core中Options模式的使用及其源码攻略 ASP.NET Core中Options模式是一种用于配置应用程序的机制。在本攻略中,我们将深入讨Options模式的使用及其源码,并提供两个示例说明。 Options模式的使用 在ASP.NET Core中,Options模式是一种用于配置应用程序的机制。Options模式允许您将配置数据…

    C# 2023年5月17日
    00
  • 详解C# 代码占用的空间

    下面是详解C#代码占用空间的攻略。 标题 首先,我们需要知道C#代码占用空间的主要原因是由于引用程序集、变量及方法等所占用的内存空间。 代码引用的程序集 在C#开发过程中,使用一些第三方库或者自己写的库是很常见的。这些库在使用时需要在代码中进行引用,而引用过程中会占用一定的内存空间。 例如,下面的代码中使用了NLog库来进行日志记录: using NLog;…

    C# 2023年5月31日
    00
  • C#将隐私信息(银行账户,身份证号码)中间部分特殊字符替换成*

    要将隐私信息中间部分替换成特殊字符,可以借助C#中的字符串处理方法来完成。具体步骤如下: 定义替换的特殊字符 可以使用任何想要的特殊字符或符号来替换隐私信息中间部分。一般来说,用“*”可以达到较好的效果。我们可以用以下代码定义特殊字符: string replacement = "*"; 获取需要替换的字符串 假设我们的隐私信息存储在一个…

    C# 2023年5月15日
    00
  • c#中task与thread的区别及使用讲解

    C#中Task与Thread的区别及使用讲解 在 C# 中,Task 和 Thread 是比较常用的多线程编程方式。Task 是从 .NET Framework 4.0 开始引入的新特性,主要用于异步编程;而 Thread 则是比较传统的多线程编程方式。 区别 1. 创建方式和语法 Task 的创建可以使用 Task 类、Task.Factory 或 asy…

    C# 2023年6月1日
    00
  • js 模拟实现类似c#下的hashtable的简单功能代码

    要模拟实现类似C#下的Hashtable的简单功能代码,我们可以使用JavaScript的对象和数组。以下是几个简单的步骤来实现Hashtable的简单功能。 创建Hashtable类 首先,我们需要创建一个Hashtable类,可以使用class语法糖来完成这一步。 class Hashtable { constructor() { this._map =…

    C# 2023年6月6日
    00
  • C#中List用法介绍详解

    C#中List用法介绍详解 List是C#中一个常用的动态数组容器,可以动态添加、删除、修改数组元素,给我们的开发提供了极大的便利。下面将对List的使用进行详细介绍。 List的定义和初始化 List的定义和初始化非常简单,只需要使用List<>和new关键字即可。 List<int> list1 = new List<int…

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