C#中的==、Equal、ReferenceEqual(转载)
1. ReferenceEquals, == , Equals
Equals , == , ReferenceEquals都可以用于判断两个对象的个体是不是相等。
a) ReferenceEquals
ReferenceEquals是Object的静态方法,用于比较两个引用类型的对象是否是对于同一个对象的引用。对于值类型它总是返回false。(因为Box以后的对象总是不同的,hehe)
b) ==是一个可以重载的二元操作符,可以用于比较两个对象是否相等。
对于内置值类型,==判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false。例如:
Int a = 100;
Double b =100;
If(a == b)
Console.WriteLine(“equal supports compare between different types!”);
上面这段程序将会输出:
equal supports compare between different types!
而对于用户定义的值类型,如果没有重载==操作符,==将是不能够使用的。例如:
Struct Userstruct1;
Userstruct1 a;
Userstruct1 b;
If(a == b)
Console.WriteLine(“can == reach this far?”)
上面的这段代码是不能够通过编译的。可以通过重载使==作用于用户定义的值类型。
对于引用类型,== 默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时候才返回true。但是.NET Framework中的类很多对==进行了重载,例如String类的==与Equals的行为相同,判断两个字符串的内容是否相等。所以在应用中,对于 系统定义的引用类型建议不要使用==操作符,以免程序出现与预期不同的运行结果。
c) Equals 作为Object内置方法,Equals支持对于任意两个CTS对象的比较。
Equals它有静态方法和可重载的一个版本,下面的程序片断解释了这两个方法的用法,
int a = 5;
int b = 5;
If(Object.Equals(a ,b))
// you can also use if(a.Equals(b))
{
Console.WriteLine(“a is equal to b”);
}
事实上,这两个版本的结果完全相同,如果用户重载了Equals,调用的都是用户重载后的Equals。Equals的静态方法的好处是可以不必考虑用于比较的对象是否为null。
Equals方法对于值类型和引用类型的定义不同,对于值类型,类型相同,并且数值相同(对于struct的每个成员都必须相同),则Equals返回 true,否则返回false。而对于引用类型,默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时 候才返回true。可以根据需要对Equals进行重载,例如String类的Equals用于判断两个字符串的内容是否相等。
StringBuilder a = new StringBuilder();
a.Append("the test a");
String s1 = a.ToString();
String s2 = "the test a";
if (s2 == s1)
Console.WriteLine("== returns true");
if (Object.Equals(s2, s1))
{
Console.WriteLine("equals returns true");
}
if (Object.ReferenceEquals(s2, s1))
{
Console.WriteLine("ReferenceEquals returns true");
}
这个实例将输出:
== returns true
equals returns true
注:对于String类,直接声明s1 = “the test a”的话,输出结果将包含 "ReferenceEquals returns true",
因为默认的,String对于声明的相同的字符串在堆上只保留一个Copy,所以s1与s2将会指向相同的Reference
在C#中,有多种比较方法,有referenceequal,equals,equalsto,但他们之间是有细微差别的。
referenceequal的实例
class MyClass {
static void Main() {
object o = null;
object p = null;
object q = new Object();
Console.WriteLine(Object.ReferenceEquals(o, p));
p = q;
Console.WriteLine(Object.ReferenceEquals(p, q));
Console.WriteLine(Object.ReferenceEquals(o, p));
}
如果要是对象都指向空引用,那么它返回true,另外,p=q;这个赋值语句,对于值类型来说,只是把地址复制给了p,并没有深拷贝。所以当比较引用时,返回true。如果比较o.equals(p),那么编译器会报错,因为equals方法不能比较null的情况。正因为如此,referenceequals方法才不受开发人员欢迎。另外,equals为实例的虚方法,referenceequals为静态方法。基元类型的==,就是操作符重载,使用的 equals方法判等。当然,还有一个equals的静态方法,静态equals与实例equals方法的唯一区别是:实例equals在对2个进行比较时,如果有一个为null,或者都是null,就会抛出异常,但静态equals方法不会,静态equals方法首先对2者检查是否为null,如果有为null的情况,就返回false,如果没有null,那么就调用实例equals方法来进行比较。
memberwiseclone()翻译为成员智能复制,呵呵,为啥智能,我就讲讲。智能就在它区别对待值类型和引用类型。
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
例如,考虑一个名为 X 的对象,该对象引用对象 A 和 B。对象 B 又引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。与此相对照,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2,它们分别是 A 和 B 的副本。B2 又引用新对象 C2,C2 是 C 的副本。
关于深拷贝和浅拷贝,深拷贝就是创建一个一摸一样的对象,浅拷贝的话仍然是同一个对象,但是却有2个计数器,2个强引用指向它。
C#中的==、Equal、ReferenceEqual(转载)的更多相关文章
- java中 == 与 equal 的区别
http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html String str1 = new String("s ...
- spring中context:property-placeholder/元素 转载
spring中context:property-placeholder/元素 转载 1.有些参数在某些阶段中是常量 比如 :a.在开发阶段我们连接数据库时的连接url,username,passwo ...
- java中“==”和equal区别
8个月以后就要正式找工作啦,我觉得现在是时候花时间好好深入研究一下以前比较混肴的知识.这就当作是自我成长的第一步! 对于String中的“equal方法”和“==”一直有点混肴,今天重新看了一下他们两 ...
- SqlServer中的merge操作(转载)
SqlServer中的merge操作(转载) 今天在一个存储过程中看见了merge这个关键字,第一个想法是,这个是配置管理中的概念吗,把相邻两次的更改合并到一起.后来在technet上搜索发现别有 ...
- String中的“equal方法”和“==”
二话不说,先来说下重写的事情: 在Java中,String .Math.还有Integer.Double....等这些封装类重写了Object中的equals()方法,让它不再比较其对象在内存中的地址 ...
- axios 中文文档(转载)
axios中文文档 转载来源:https://www.jianshu.com/p/7a9fbcbb1114 原始出处:lewis1990@amoy axios 基于promise用于浏览器和node. ...
- Chai.js断言库API中文文档【转载】
基于chai.js官方API文档翻译.仅列出BDD风格的expect/should API.TDD风格的Assert API由于不打算使用,暂时不放,后续可能会更新. BDD expect和shoul ...
- MyBatis学习总结(三)——优化MyBatis配置文件中的配置(转载)
本文转载自:http://www.cnblogs.com/jpf-java/p/6013548.html 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置 ...
- IE中的条件注释(转载自网络)
IE条件注释是微软从IE5开始就提供的一种非标准逻辑语句,作用是可以灵活的为不同IE版本浏览器导入不同html元素,如:样式表,html标签等.很显然这种方法的最大好处就在于属于微软官方给出的兼容解决 ...
随机推荐
- LLBLGen代码生成工具
LLBLGen代码生成工具 下载地址:http://www.llblgen.com/ 最新版本4.2 概述 LLBLGen是一个数据访问的解决方案; 你使用LLBLGen创建实体/域模型,定义了映射和 ...
- [转]javascript指定事件处理程序包括三种方式:
javascript指定事件处理程序包括三种方式: (1):DOM0级事件处理程序 如: 代码如下: var btn=document.getElementById("mybtn" ...
- C# 重新改变数组的长度
重新改变数组的长度 System.Array.Resize(ref FieldName, j);
- axel源码学习(0)——程序逻辑
axel简介 axel是一个命令行下的轻量级http/ftp 下载加速工具,支持多线程下载和断点续传,支持从多个镜像下载同一文件. axel的用法如下: 图 0.1 axel usage axel 粗 ...
- Hibernate - 使用注解完成映射
除了使用XML配置来映射对象和数据库表,还可以使用注解来完成持久化.使用注解需要导入Hibernate Annotations扩展包 @Entity -加在类的前面,将类声明为持久化类. -javax ...
- Hibernate学习笔记--------1.单表操作
一.hibernate基本开发步骤 1.引入包,官网下载的包,目录\lib\required下的jar都加进去,这里使用的是 hibernate-release-5.2.1.Final 2.编写配置文 ...
- uiautomator日志文件转换为xml格式文件
如果想把uiautomator的日志文件,转换成漂亮的xml文件,那么可以使用automator-log-converter.jar工具, 工具使用方法: 使用工具automator-log-conv ...
- C#前端頁面判斷控件
var chbClass = document.getElementById("<%=DDL_CheckboxUserClass1.ClientID %>" + &qu ...
- JNDI初认识
JNDI即Java命名和目录接口,英文全称为Java Naming and Directory Interface,从字面上似乎十分晦涩,下面从理论和实际项目应用方面来阐述. 1.命名:在我们实际生活 ...
- 实现html伪静态竟然那么简单
1.单参数 功能: 把:www.44721.cn/movie.asp?id=123 伪静态为:www.44721.cn/movie.asp?123.html 代码如下: ASP/Visual Basi ...