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一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...
随机推荐
- MFC自创建类了解
CxxxxView 视窗类 所有的按键 等消息都先在这里响应 CxxxxDoc 文档类 CMainFrame 框架类 CxxxxApp 应用程序类 CxxxxView类中的 OnDraw函数 在窗口改 ...
- Java was started but returned exit code=13
安装Eclipse(32位)后打开报错:Java was started but returned exit code=13 解决方法: 1,首先我查看了我当前安装的JDK版本,发现是64位的: 2, ...
- runtime 运行时机制 完全解读
runtime 运行时机制 完全解读 目录[-] import import 我们前面已经讲过一篇runtime 原理,现在这篇文章主要介绍的是runtime是什么以及怎么用!希望对读者有所帮助! ...
- 卓越网的kindle paperwhite
卓越网的kindle paperwhite, 899元的价钱,好吸引啊,我是不是也应该买一个呢,从卓越网中看见kindle paperwhite的1代开始,一直想买,等到现在的2代也出了,也继续在考虑 ...
- 一句话输出网站404页面,REFER及相关排序
cat www.log|awk '$9~/404/ {print $7"," $11}'|sort|uniq -c|sort -nr > ./www404.csv
- AltiumDesigner14板框定义及3D显示图文教程
很多人都跟我反应说AD14不能定义板框大小,或者说是不知道怎么定义板框的大小,确实AD14的操作和AD13或者是AD10的版本斗有一些差异,尤其是现在最新的版本AltiumDesigner14.3.1 ...
- 【笔试&面试】C#中的程序集
1. C#中的程序集(Assembly) 答:程序集是包含一个或多个类型定义文件和资源文件的集合.它允许我们分离可重用类型的逻辑表示和物理表示. 程序集是一个可重用.可实施版本策略和安全策略 ...
- 【HDOJ】1493 QQpet exploratory park
超水的动态规划.最后要对概率求Sigma. #include <cstdio> #include <cstring> #include <cstdlib> #def ...
- delphi编写dll心得, 谢谢原作者的分享。转
delphi编写dll心得 1.每个函数体(包括exports和非exports函数)后面加 'stdcall;', 以编写出通用的dll2.exports函数后面必须加'export;'(放在'st ...
- 算法导论(第三版)Exercises2.3(归并排序、二分查找、计算集合中是否有和为X的2个元素)
2.3-1: 3 9 26 38 41 49 52 59 3 26 41 52 9 38 49 57 3 41 52 26 38 57 9 49 3 41 52 26 38 ...