在比较Equals 和 ==的区别前。我们先来了解下相关的知识

C#数据类型

1、值类型

值类型有:

  值类型包括:简单类型、结构类型、枚举类型。

  byte(1)、sbyte(1)、short(2)、ushort(2)、int(4)、uint(4)、long(8)、ulong(8)、float(4)、double(8)、decimal(8)、char、bool、枚举、结构。

  上述中括号中的数字表示字节数,byte、ushort、uint、ulong 为无符号类型(没有负数),顺便说一下 sbyte 是有符号的字节。

2、引用类型

  引用类型有:对象(Object)类型、类类型、接口、代表元、字符串类型、数组。

new 运算符

在 C# 中, new 关键字可用作运算符、修饰符或约束。

1、 new 运算符

  用于创建对象和调用构造函数。

2、new 修饰符

  用于向基类成员隐藏继承成员。

3、new 约束

  用于在泛型声明中约束可能用作类型参数的参数的类型。

需注意一点:凡是用new运算符就会在堆内存中开辟空间存放引用(引用地址存放在栈上)对象的值

==  和 Equals 的区别

  1. == 是一个运算符。

  2.Equals则是string对象的方法,可以.(点)出来。

我们比较无非就是这两种 1、基本数据类型比较  2、引用对象比较

1、基本数据类型比较

  ==和Equals都比较两个值是否相等。相等为true 否则为false;

2、引用对象比较  

  ==和Equals都是比较栈内存中的地址是否相等 。相等为true 否则为false;

需注意几点:

  1、string是一个特殊的引用类型。对于两个字符串的比较,不管是 == 和 Equals 这两者比较的都是字符串是否相同;

  2、当你创建两个string对象时,内存中的地址是不相同的,你可以赋相同的值。

    所以字符串的内容相同。引用地址不一定相同,(相同内容的对象地址不一定相同),但反过来却是肯定的;

  3、基本数据类型比较(string 除外) == 和 Equals 两者都是比较值;

接下来我们来挨个挨个看实例:

  1、基本数据类型比较:==  和 Equals 都比较具体的值

            int i1 = 8;
int i2 = 8; bool bo1 = i1 == i2; //true
bool bo2 = (object)i1 == (object)i2; // 装箱后变成引用类型,引用不同 故为false
bool bo3 = (i1).Equals(i2); //true 比较的是值

2、来看一个地址不同,内容相同的比较。== 比较地址, Equals比较值

            //使用了new运算符就会在内存中创建对象,地址是不相同的。字符串内容相同
string str3 = new string(new char[] { 'a', 'b', 'c' });
string str4 = new string(new char[] { 'a', 'b', 'c' }); bool b3 = (object)str3 == (object)str4; //false 转化成object后 是比较地址,这里内存中的地址是不相同的
bool b4 = ((object)str3).Equals((object)str4); //true 此时Equals依然是比较值

3、string字符串比较:==  和 Equals 同样也是比较具体的值

           //string是特殊的引用类型。只要是字符串比较,不管是"=="还是"Equals"都是比较字符串的内容
string str1 = "abc";
string str2 = "abc"; bool b1 = str1 == str2; //true
bool b2 = str1.Equals(str2); //true //使用了new运算符就会在内存中创建对象,地址是不相同的。字符串内容相同
string str3 = new string(new char[] { 'a', 'b', 'c' });
string str4 = new string(new char[] { 'a', 'b', 'c' }); bool b3 = str3 == str4; //true 字符串比较 是比较具体的值,这里内存中的地址是不相同的
bool b4 = str3.Equals(str4); //true bool b5 = str1 == str3; //true
bool b6 = (str1).Equals(str3); //true object str5 = "abc"; //定义一个变量 str5并赋值为 abc
object str6 = "abc"; //定义一个变量 str6并指向字符串abc bool b7 = str5 == str6; //true
bool b8 = (object)str5 == (object)str6; //但这样就是比较引用是否相同,因为str5 和 str6 引用同一个实例 即为 true
bool b9 = str5.Equals(str6); //true

在上个列子中b3和b4都是true,我们来看看str3和str4在内存中的地址是否相等?其实是不相等的。用new操作符创建的对象都会在内存中分配一个新的内存地址,同时也可以证明这里比较的是值,而不是地址;更进一步证明相同内容的对象地址不一定相同。

如何调出内存窗口?如图:(启动调试后,这里可以调出多个内存窗口)用来比较地址

4、引用类型比较: ==和Equals都是比较栈内存中的地址是否相等

class MyClass
{
public string name;
public MyClass(string name)
{
this.name = name;
} }
   //------------------------测试-----------------------------
MyClass str7 = new MyClass("abc");
MyClass str8 = new MyClass("abc"); bool b10 = str7 == str8; //这里是引用类型比较(不是string字符串比较)所有比较是不是对同一个对象的引用,这里显然是内存中两个不同的引用对象。故为false
bool b11 = str7.Equals(str8); //同上 MyClass str9 = str7; //str7的地址赋值给str9。 bool bl2 = str7 == str9; //true 引用同一个对象
bool bl3 = str7.Equals(str9); //true object str10 = new object();
object str11 = new object(); bool b12 = str10 == str11; //false
bool b13=str10.Equals(str11); //false

同样我们开看看str7 str8 str9 分别在内存中的地址,红框标记(str7,str9)可以看出地址是相等的

看到这里也许你疑惑了,既然引用类型比较 == 和Equals都是比较地址,那就没区别吗?

Equals是string类下的一个方法,既然知道它的来路。我们就可以看看它内部源码的实现,打开Reflector查找string。

找到Equals(Object obj) 和Equals(string value)

看到内部也是用==来实现的,并且看到Object的比较是转换成string后比较。

好了,继续来讲,在引用类型比较中,== 和Equals都是比较地址外,Equals突出的地方。一个对象除了地址相同。还有其他独有的特征。

比如我们要比较某人都来自中国(内存地址),并且都来自中国香港(内存地址独有的特征或性质),

当符合这两个条件我们才说明这个对象是相等的。那么此时 == 和Equals都无能为力。但Equals有它鹤立鸡群的地方。

查看Equals定义会发现,Equals是virtual方法:  public virtual bool Equals(object obj); 既然是virtual我们就可以重写Equals方法,来编写自己的业务逻辑

嗯!来编写一个测试类,并且override Equals方法

 class MyClass
{
public string country; //国家
public string city; //城市
public MyClass(string country, string city)
{
this.country = country;
this.city = city;
}
public override bool Equals(object obj)
{
string ci = ((MyClass)obj).city;
string co = ((MyClass)obj).country;
if (ci == "香港" && co == "cn")
return true;
return false;
}
}

测试:

            MyClass str7 = new MyClass("cn","香港");
MyClass str8 = new MyClass("cn","香港");
MyClass str18 = new MyClass("cn", "台湾"); bool na = str7.Equals(str8); //true
bool an = str7.Equals(str18); //false

最后谈谈这两个有什么区别:

            string str1 = "abc";
string str3 = new string(new char[] { 'a', 'b', 'c' });

以上这两句话大家应该都见得多,比如str3这句笔试题居多,大体都是创建了几个string对象。回答理所当然是两个。一个是"abc"驻留,

一个是new string("abc")的时候在堆内存上的数据"abc",栈内存则保存了对"abc"的引用,不是对象。通俗一点就是栈上的引用地址指向堆中的值或内容。

来看看str1这句,这并没有创建对象。即没有在内存中分配空间。因为没有使用new运算符,这里仅仅是声明了一个指向对象的引用变量str1,暂时指向"abc",

所以这里只创建了一个string对象,所以要区分用new和没有用new的方式

看看下面这个列子是创建了3个对象。因为字符串是不可变的

         string x = "ab";
string y = "a";
string x = x + y;

不知道C#中有没有常量池这一概念。还有看到网上很多这样的 string str = new string("abc") 可我真的没找到stirng的这个重载函数

---------Equals 和 == 的区别末前就了解这么多。知识比较基础,阅历还不够。刚出来混的。不足之处还请多多指教,文明发言。共同学习。谢谢!

转--https://www.cnblogs.com/nsky/archive/2013/03/01/2939268.html

Equals 和 == 的区别--转的更多相关文章

  1. java equals和==的区别

    大概说equals和==都比较的是什么: 1. boolean tem = a == b; 首先==比较的肯定是地址,从堆栈的角度说也就是说==比较的是栈上面的内容.因为栈是用来存放地址或是java中 ...

  2. equals与==的区别

    equals与==的区别. 下面是equals的源码 public boolean equals(Object anObject) { if (this == anObject) { //如果两个对象 ...

  3. equals和==的区别 你真的掌握了吗?

    PS:最近读Java编程思想的时候发现了一些小问题.就是equals方法和==,感觉自己是真正掌握了,其实并没有.简单的记录一下. 学习内容: 1.equals 和 == 的区别  equals和== ...

  4. 【ASP.net】Equals 和 == 的区别

    在比较Equals 和 ==的区别前.我们先来了解下相关的知识 C#数据类型 1.值类型 值类型有: 值类型包括:简单类型.结构类型.枚举类型:引用类型包括:Object 类型.类类型.接口.代表元. ...

  5. 【java】由equals和==的区别引出的常量池知识

    equals和==的区别,百度查到的结果大都是:equals比较的是值,==比较的是引用地址. String str1 = "abc"; String str2 = "a ...

  6. 比较compareTo与equals及==的区别

    1.compareTo: 附上:源码: public int compareTo(String anotherString) {         int len1 = value.length;   ...

  7. Java笔记——equals和==的区别

    摔在这里几次,还是记下来吧. 原文:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html -------------- ...

  8. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

  9. equals()和hashCode()区别?

    equals()和hashCode()区别? ------------------------------------------------- equals():反映的是对象或变量具体的值,即两个对 ...

  10. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

随机推荐

  1. UNIGUI:How to redirect and close session?

    Hello, i would have 2 unigui app. the first app is a simple authentification app and second will be ...

  2. 如何搭建一个GitHub在自己的服务器上?

    摘自:http://blog.csdn.net/yangzhenping/article/details/43937595

  3. The Quantum L3 router and floating IPs

    This post shows how the Quantum L3 Agent uses the Linux IP stack to implement the Quantum L3 Routing ...

  4. Spring- 通过Xml的方式完成Bean的实例化

    传统应用程序可以通过反射方式进行实例化Bean,而Spring Ioc 容器则需要根据Bean定义的配置元数据使用反射机制来创建Bean.在Spring Ioc 容器中主要有以下几种创建Bean实例的 ...

  5. Linux- 自动备份MySQL数据库脚本

    数据安全很重要,所以日常中需要对数据库进行备份.

  6. 利用create-react-app从零开始搭建React移动端环境

    一 开始 1 全局安装脚手架 npm install -g create-react-app 这有个坑,就是在window下安装一直会报错,报错信息如下: 解决办法:在开始菜单栏里打开cmd的时,右击 ...

  7. poj 1080 Human Gene Functions(lcs,较难)

    Human Gene Functions Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19573   Accepted:  ...

  8. Unity3D之Mesh(三)绘制四边形

    前言: 由於之前的基本介紹,所以有關的知識點不做贅述,只上案例,知識作爲自己做試驗的記錄,便於日後查看. 步驟: 1.創建一個empty 的gameobject: 2.添加一個脚本給這個game ob ...

  9. python基础-变量

    1.什么是变量? 其实就是给数据起个名字而已.在python中你不想要关心数据类型,因为在你赋值的时候它已经自己帮你识别了 2.创建变量时候会在内存中开辟一个空间,具体的细节不需要咱们关心,解释器会分 ...

  10. Log4j_学习_00_资源帖

    一.log4j2 1. log4j使用教程详解(怎么使用log4j2) 2.Log4j2的基本使用 二.log4j 1.[转]最详细的Log4J使用教程 2.最详细的Log4j使用教程 3.log4j ...