首页 > 编程语言 >C# 中==与Equals方法比较

C# 中==与Equals方法比较

时间:2023-06-05 22:04:08浏览次数:28  
标签:Console string C# Equals Person WriteLine new 方法

先来段代码,如下:

static void Main(string[] args)
        {

            string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
            string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });


            Console.WriteLine(a == b);  //True
            Console.WriteLine(a.Equals(b));  //True

            object objA = (object)a;
            object objB = (object)b;

            Console.WriteLine(objA == objB);   //False
            Console.WriteLine(objA.Equals(objB));  //True


            Person p1 = new Person("user");
            Person p2 = new Person("user");

            Console.WriteLine(p1 == p2);    //False
            Console.WriteLine(p1.Equals(p2));  //False

            Person p3 = new Person("user");
            Person p4 = p3;
            Console.WriteLine(p3 == p4);   //True
            Console.WriteLine(p3.Equals(p4));  //True



            Console.Read();

        }

C# 中==与Equals方法比较_值类型

答案是 truetruefalsetruefalsefalsetruetrue。 

为什么会出现这个答案呢?

因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。

总结如下:

1. 对于值类型,==和Equals()等价,都是比较存储信息的内容(即比较两个对象的值是否相同);

2. 对于除string之外的引用类型,==比较的是栈的内容是否相同(即是否指向同一个堆中地址),Equals()判断是否对同一个对象的引用(即堆中的内容是否相同);

3. string是一种特殊的引用类型,在C#语言中,重载了Object对象的很多方法(包括equals()方法),使string对象用起来就像是值类型一样

   下图为string类中重载的Equals方法描述:

    

C# 中==与Equals方法比较_字符串_02

4. 对于一些自定义类,我们看看是否有重载Equals方法,如果没有则默认为基类的Equals方法(如果基类没有重载Equals方法则为Object类Equals方法),Object类中Equals方法比较也是栈中的地址,而不是堆中的内容。

     下图为Object类中Equals方法描述:

    

C# 中==与Equals方法比较_字符串_03

      因此我们不难理解下面的结果:    

         

Person p1 = new Person("user");
            Person p2 = new Person("user");            Console.WriteLine(p1 == p2);    //False
            Console.WriteLine(p1.Equals(p2));  //False

5. 对于string类型有必要强调一下   

           

string a = "hello";
            string b = "hello";            object objA = (object)a;
            object objB = (object)b;            Console.WriteLine(objA == objB);   //True


            Console.WriteLine(objA.Equals(objB));  //True

           结果:True,True

    这是因为系统并没有给字符串b分配内存,只是将"hello"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。



标签:Console,string,C#,Equals,Person,WriteLine,new,方法
From: https://blog.51cto.com/u_4018548/6419777

相关文章

  • .static 和const分别怎么用,类里面static和const可以同时修饰成员函数吗。
    static的作用:对变量:1.局部变量:在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。  1)内存中的位置:静态存储区  2)初始化:局部的静态变量只能被初始化一次,且C中不可以用变量对其初始化,而C++可以用变量对其初始化。  3)作用域:作用域仍为局部作用域,当定义它的......
  • C# 中的CTS, CLS, CLR 的理解
     ......
  • 异步编程async体会
    namespace异步编程{classProgram{staticvoidMain(string[]args){Console.WriteLine("mianthisisasync{0}",Thread.CurrentThread.ManagedThreadId);Do();......
  • Elastic_Search 和java的入门结合
    1,pom文件添加依赖... 2,config配置文件  3,写接口文件 ......
  • variable-sized object may not be initialized
    #include<stdio.h>intmain(void){intN;scanf("%d",&N);inta[N]={0};//错误在这,可以用变量定义数组,但不能初始化for(inti=0;i<N;++i){scanf("%d",&a[i]);}intM,sum=0;scanf("%d",&......
  • 探秘C#中的yield关键字
     在"C#中,什么时候用yieldreturn"中,我们了解到:使用yieldreturn返回集合,不是一次性加载到内存中,而是客户端每调用一次就返回一个集合元素,是一种"按需供给"。本篇来重温yieldreturn的用法,探秘yield背后的故事并自定义一个能达到yieldreturn相同效果的类,最后体验yieldbreak的用......
  • 用户故事与敏捷方法读后感(一)
    本书讲解了如何去确定一个软件系统应该做什么还有软件需求调研人员如何与不同的人沟通。需求文档是重中之重,但是大量预先的需求收集和文档会很容易导致项目失败。最常见的是需求文档变成软件开发的目的。我们不应为了写文档而写文档。文档只是为了软件开发更为方便的一种工具,我们......
  • CVE-2023-2825-GitLab目录穿越poc
    GitlabCVE-2023-2825目录穿越漏洞前言昨天GitLab出了一个版本目录穿越漏洞(CVE-2023-2825),可以任意读取文件。当时我进行了黑盒测试并复现了该漏洞。“Anunauthenticatedmalicioususercanuseapathtraversalvulnerabilitytoreadarbitraryfilesontheserver......
  • cpufreq的初始化讲解
    cpufreq初始化cpufreq的初始化,通过调用cpufreq_register_driver接口,完成一系列的policy、governor和driver配置。驱动moduleinit入口driver编写module_init的函数,在初始化中使用cpufreq_register_driver注册驱动cpufreq_register_driver中会完成增加总线设备、节点创建等操......
  • Golang高性能编程--slice的学习总结
    在go语言中,数组变量属于值类型,因此当一个数组变量被复制或者传递时,实际上会复制整个数组。eg,将a赋值给b,修改a中的元素,并不会修改b中的元素。为了避免复制数组,一般会传递指向数组的指针。packagemainimport"fmt"funcmain(){ a:=[...]int{1,2,3} b:=a a[0]=100......