分享

Equals 和 == 的区别

 昵称10504424 2013-03-04

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 都比较具体的值

 

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

 

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

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

 

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


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

 

 同样我们开看看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方法

 

 测试:

 

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

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

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

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

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

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

 

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

 

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

 

 

作者: nsky
出处: http://nsky.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,共同学习;共同进步;但不能乱搞!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多