C#--对象的相等比较
对象相等比较机制对于引用类型的变量和值类型的变量来说是不同的,下面分别介绍引用类型和值类型的相等比较.
首先来看System.Object的部分定义:
public class Object
{
// 摘要:
// 确定指定的 System.Object 是否等于当前的 System.Object。
// 参数:
// obj:与当前的 System.Object 进行比较的 System.Object。
// 返回结果:
// 如果指定的 System.Object 等于当前的 System.Object,则为 true;否则为 false。
public virtual bool Equals(object obj);
//
// 摘要:
// 确定指定的 System.Object 实例是否被视为相等。
// 参数:
// objB:要比较的第二个 System.Object。
// objA:要比较的第一个 System.Object。
// 返回结果:
// 如果 objA 是与 objB 相同的实例,或者如果两者均为空引用,或者如果 objA.Equals(objB) 返回 true,则为 true;否则为
// false。
public static bool Equals(object objA, object objB);
//
// 摘要:
// 确定指定的 System.Object 实例是否是相同的实例。
// 参数:
// objB:要比较的第二个 System.Object。
// objA:要比较的第一个 System.Object。
// 返回结果:
// 如果 objA 是与 objB 相同的实例,或者如果二者都为空引用,则为 true;否则为 false。
public static bool ReferenceEquals(object objA, object objB);
}
}
System.Object中定义了三个比较是否相等的方法.还有一个运算符(==),这个运算符可以比较引用,也可以比较值.
下面来详细的介绍这四个方法:
1。引用类型的相等比较
方法1:public static bool ReferenceEquals(object objA, object objB);
描述:ReferenceEquals()是个静态方法,测试两个引用是否指向类的同一个实例,即两个变量中存的地址是否是同一个地址.
例子:
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SomeClass sc1 = new SomeClass();
SomeClass sc2 = new SomeClass();
//输出false
Response.Write(ReferenceEquals(sc1, sc2) + "<br/>");
//输出false
Response.Write(ReferenceEquals(sc1, null) + "<br/>");
//输出false
Response.Write(ReferenceEquals(null, sc1) + "<br/>");
//输出true
Response.Write(ReferenceEquals(null, null) + "<br/>");
}
} public class SomeClass
{ }
方法2:public virtual bool Equals(object obj);
描述:这个方法也比较引用,但因为该方法是虚拟的,所以可以在自己的类中重写它,按值来比较对象.
例子:
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SomeClass sc1 = new SomeClass(10);
SomeClass sc2 = new SomeClass(11);
//输出false
Response.Write(sc1.Equals(sc2) + "<br/>");
//输出false
Response.Write(sc1.Equals(null) + "<br/>");
//输出true
Response.Write(sc1.Equals(sc1) + "<br/>");
}
} public class SomeClass
{
private int _age; public SomeClass(int age)
{
this._age = age;
} public override bool Equals(object obj)
{
SomeClass sc = obj as SomeClass;
if (sc == null)
{
return false;
} return this._age == sc._age;
}
}
方法3:public static bool Equals(object objA, object objB);
描述:Equals的静态版本与其虚拟实例版本的作用相同,其区别是静态版本带有两个参数.并对它们进行比较.这个方法可以处理两个对象中有一个是null的情况,因此,如果有一个对象为null,则会抛出异常.
注意:如果两个对象都为null,则返回true.
如果仅有一个对象为null,返回false.
如果两个对象都不为null,则会调用抽象的Equals方法.
这表明,如果是比较两个对象,重写了虚拟的Equals方法,相当于重写了静态的Equals方法.
例子:
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SomeClass sc1 = new SomeClass(10);
SomeClass sc2 = new SomeClass(11);
//输出true
Response.Write(object.Equals(null, null) + "<br/>");
//输出false
Response.Write(object.Equals(sc1, null) + "<br/>");
//输出false
Response.Write(object.Equals(sc1, sc2) + "<br/>");
}
} public class SomeClass
{
private int _age; public SomeClass(int age)
{
this._age = age;
} public override bool Equals(object obj)
{
SomeClass sc = obj as SomeClass;
return this._age == sc._age;
}
}
比较运算符:==
描述:这个运算符介于严格的值比较和严格的引用比较之间.
例子:
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SomeClass sc1 = new SomeClass();
SomeClass sc2 = new SomeClass();
//输出false
Response.Write(sc1 == sc2);
}
} public class SomeClass
{ }
2。值类型
在进行值比较时,ReferenceEquals仍然用于比较引用,如下例:
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//输出false
Response.Write(ReferenceEquals(1,1));
}
}
输出false的原因是ReferenceEquals比较的引用,对于两个值类型的1和1,分别执行了装箱操作,导致两个参数实际上是不同的引用.
在进行值比较时Microsoft在System.ValueType类中已经重载了实例方法Equals,所以:
Equals比较的就是值:
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int i = 1;
//输出true
Response.Write(i.Equals(1));
}
}对于静态的Equals来说.实际调用的是虚拟的Equals方法.
public partial class Equals_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//输出true
Response.Write(object.Equals(1,1));
}
}
小结:
ReferenceEquals使用比较的是引用,若两个实例指向同一个对象,则返回true,否则返回false.
静态的Equals方法在比较非空对象和值时主要调用虚拟的Equals方法.主要看虚拟的Equals方法在被重写时是如何写的.
C#--对象的相等比较的更多相关文章
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- JS核心系列:浅谈原型对象和原型链
在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象(Object)和函数对象(Function). 一般而言,通过new Function产生的对象是函数对象,其他对 ...
- Chrome出了个小bug:论如何在Chrome下劫持原生只读对象
Chrome出了个小bug:论如何在Chrome下劫持原生只读对象 概述 众所周知,虽然JavaScript是个很灵活的语言,浏览器里很多原生的方法都可以随意覆盖或者重写,比如alert.但是为了保证 ...
- XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法
在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...
- ASP.NET内置对象的总结
1. Response对象可形象的称之为响应对象,用于将数据从服务器发送回浏览器. 实例源码:链接: http://pan.baidu.com/s/1dDCKQ8x 密码: ihq0 2. Requ ...
- ADO.NET对象的详解
1. Connection 类 和数据库交互,必须连接它.连接帮助指明数据库服务器.数据库名字.用户名.密码,和连接数据库所需要的其它参数.Connection对象会被Command对象使用,这样就能 ...
- 对Castle Windsor的Resolve方法的解析时new对象的探讨
依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...
随机推荐
- 1105PHP笔记001
关于抽象类:abstract class Car{ abstract function getMaximumSpeed();}class FastCar extends Car{ function g ...
- web前端知识
4.表格与表单 4.1 动态添加行 <script language=”javascript”> window.onload=function(){ var oTr = document. ...
- EDIT编辑框
编辑框 编辑框的主要作用是让用户输入文本,例如要求用户在编辑框中输入密码的文本. .基础知识 编辑框里的文本可以是单行,也可以是多行,后者的风格取值为 ES_MULTILINE.一般对于多行文本编辑框 ...
- spark 监控--WebUi、Metrics System
Spark 监控相关的部分有WebUi 及 Metrics System; WebUi用于展示Spark 资源状态.Metrics System 整合的指标信息. Ui相关流程 Spark集群启动之后 ...
- Iterator pattern(c++实现)
概述: 在现在的电视机中,我们使用[后一个]和[前一个]按钮可以很方便的换台,当按下[后一个]按钮时,将切换到下一个预置的频道.想象一下在陌生的城市中的旅店中看电视.当改变频道时,重要的不是几频道,而 ...
- Android AlertDialog全屏显示去除白色边框
使用styles.xml风格: Style.xml代码 <style name="FullScreenDialog" parent="android:style/T ...
- Android调用系统相机和文件浏览器
//拍照功能,调用系统的相机功能 Intent intent2 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResul ...
- HDU_2032——杨辉三角
Problem Description 还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 1 ...
- 如何将Java Web项目部署到服务器上
转自:(此处更详细)http://blog.csdn.net/gulu_gulu_jp/article/details/50994003 一.前言 前面我们已经尝过了在云服务器上部署代码的甜头了,现在 ...
- nutch和solr集成
Linux下的Nutch和solr集成 3.1.Nutch安装 l 解压 tar -zxvf apache-nutch-1.4-bin.tar.gz l 终端下cd到目录 apache-nutch- ...