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一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...
随机推荐
- PowerShell: 如何解决File **.ps1 cannot be loaded because the execution of scripts is disabled on this sy
PowerShell 默认不允许执行*.ps1脚本文件.运行ps1文件会得到下面的错误: File C:\Temp\Test.ps1 cannot be loaded because the exec ...
- getAttribute:取得属性; setAttribute:设置属性。
input.setAttribute("title"); 当它是一个值,就是取值. input.setAttribute("title", "hell ...
- FileWriter
package file; import java.io.File; import java.io.FileWriter; import java.io.IOException; public cla ...
- hql 多表查询
sql 单表/多表查询去除重复记录单表distinct多表group by select h from Hytxbz as h,Tgbzk as t where h.hytxbzid=t.hytxbz ...
- FPGA那些事 --经典总结
规范很重要 工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎是不可实现的.逻辑设计也是这样:如果不按规范做的话,过一个月后调试时发现有错,回头再看自 ...
- 转:为什么需要htons(), ntohl(), ntohs(),htons() 函数
为什么需要htons(), ntohl(), ntohs(),htons() 函数: 在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺序的问题.这是就可能用到htons(), ntohl ...
- Entity Framewor 学习笔记 (Enum)
EF 6 支持Enum 的处理 首先说一下 mysql 和 sql server 的区别 mysql 是有 Enum 这个类型的 , insert 时是放入 int , 出来的时候它会是 string ...
- PCB的阻抗控制
多层板的结构: 通常我们所说的多层板是由芯板和半固化片互相层叠压合而成的,芯板是一种硬质的.有特定厚度的.两面包铜的板材,是构成印制板的基础材料.而半固化片构成所谓的浸润层,起到粘合芯板的作用,虽然也 ...
- post 相比get 有很多优点,为什么现在的HTTP通信中大多数请求还是使用get?
好吧, 除了哲学方式的回答以外,下面是一个浏览器从业人员的看法 事实上GET 和 POST 在实践上面有非常大的区别,这两种方法在语义上面并非能互相取代. POST 是否比 GET 安全 是的, PO ...
- mysql之事务
事务处理 begin 开始一个事物 commit 事务确认 rollback 事务回滚 end 事务结束 innodb下可以实现事务 开始执行事务时如果 ...