一、等值性——Equals()方法

有时候我们需要比较两个对象是否相等,比如在一个ArrayList中进行排序查找等操作时。

System.Object提供了Equals()虚方法:

class Object

{

public virtual Boolean Equals(object o)

{

if (this == o) return true;

else return false;

}

}

这种判断方式非常简单:直接比较是两个引用是否指向的是同一对象。但这样比较是不确切的。所以我们需要重写该方法,提供更合适的实现方式。

重写时Equals()四大原则?我们在离散数学中好像学过这个呀:

  • 自反。即x.Equals(x)必须为true。
  • 对称。即x.Equals(y)和y.Equals(x)必须返回同样的值。
  • 可传递。即如果x.Equals(y)和y.Equals(z)都返回true,则x.Equals(z)也返回true。
  • 前后一致。如果两个对象的值没变,那么多次比较的值都应该是相同的。

重写思路

  • 1. 如果参数obj为null,返回false。      因为在非静态方法中,使用this表示的当前对象肯定不是Null。
  • 2. 如果this和obj参数指向同一实例对象,返回true。    这样省略字段比对过程,提高性能。
  • 3. 如果this 和obj参数指向的对象类型不同,则返回false。
  • 4. 比较this和obj中每个实例字段,如果字段不相等则返回false。
  • 5. 调用基类的Equals方法,如果调用结果为false,则返回false;
  • 6. 至此,才能返回true。
二、惟一性——ReferenceEquals() 方法

惟一性指两个引用指向同一对象。一旦我们的类重写了Ojbect的Equals方法,我们就不能用它来检测唯一性了。Object提供了另一个静态方法ReferenceEquals()

public class Object {

public static Boolean ReferenceEquals(Object objA, Object objB) {

return (objA == objB);

}

}

但是我们尽量不要在C#中用==操作符来判断唯一性,除非两参数都为Object类型。因为有可能其中一个参数类型会重写==操作符,使他产生了其他语义。

实例体验?

class Animal { };

static void Main(string[] args)
        {
            Animal a1 = new Animal();
            Animal a2 = a1;
            Console.WriteLine(Object.ReferenceEquals(a1, a2));                //true,指向同一对象
            a2 = new Animal();
            Console.WriteLine(Object.ReferenceEquals(a1, a2));                //false,a2重新指向新对象
            int number = 100;
            Console.WriteLine(Object.ReferenceEquals(number, number));//false,值类型Number两次装箱到不同的对象中
            Console.Read();
        }

三、散列码——GetHashCode() 方法

System.Object提供了虚方法GetHashCode()从一个对象上得到Int32的散列码。该方法返回的是在整个应用程序域中保证惟一的值,该值在对象整个生存周期内都不会改变。

如果我们重写了类的Equals()方法,那么我们最好也重写GetHashCode()方法,否则编译器可能会产生警告信息。因为System.Collections.Hashtable类要求两个相等的对象具有相同的散列值。

四、克隆——ICloneable接口

如果一个类允许实例被拷贝,则继承ICloneable接口。

Public interface ICloneable{ object Clone();}

浅拷贝?

当对象的字段值被拷贝时,字段引用的对象不会被拷贝。实现时可以调用Object的MemberwiseClone方法即可。

深拷贝?

对象实例中字段引用的对象也进行拷贝。深拷贝后,新创建的对象和原对象没有任何公用的东西,改变一个对象时也不会影响另外一个。

CLR via C#(04)- 本是同根生的更多相关文章

  1. CLR 初步

    1. 源代码编译为托管模块 程序在.NET框架下运行,首先要将源代码编译为 托管模块.CLR是一个可以被多种语言所使用的运行时,它的很多特性可以用于所有面向它的开发语言.微软开发了多种语言的编译器,编 ...

  2. CLR via C#深解笔记七 - 自动内存管理(垃圾回收)

    每个应用程序都要使用这样或者那样的资源,比如文件.内存缓冲区.屏幕空间.网络连接.数据库资源等.事实上,在面向对象的环境中,每个类型都代表可供程序使用的一种资源. 要使用这些资源,必须为代表资源的类型 ...

  3. [CLR via C#]21. 自动内存管理(垃圾回收机制)

    目录 理解垃圾回收平台的基本工作原理 垃圾回收算法 垃圾回收与调试 使用终结操作来释放本地资源 对托管资源使用终结操作 是什么导致Finalize方法被调用 终结操作揭秘 Dispose模式:强制对象 ...

  4. 【CLR】解析CLR的托管堆和垃圾回收

    目录结构: contents structure [+] 为什么使用托管堆 从托管堆中分配资源 托管堆中的垃圾回收 垃圾回收算法 代 垃圾回收模式 垃圾回收触发条件 强制垃圾回收 监视内存 对包装了本 ...

  5. 重温CLR(十五) 托管堆和垃圾回收

    本章要讨论托管应用程序如何构造新对象,托管堆如何控制这些对象的生存期,以及如何回收这些对象的内存.简单地说,本章要解释clr中的垃圾回收期是如何工作的,还要解释相关的性能问题.另外,本章讨论了如何设计 ...

  6. CLR via C# 读书笔记-21.托管堆和垃圾回收

    前言 近段时间工作需要用到了这块知识,遂加急补了一下基础,CLR中这一章节反复看了好多遍,得知一二,便记录下来,给自己做一个学习记录,也希望不对地方能够得到补充指点. 1,.托管代码和非托管代码的区别 ...

  7. Mac安装Ubuntu18.04双系统经验以及感悟

    1.扯一会 提到Mac很多人估计会觉得高大上,其实我也是这么认为的,因为我在13年之前用的不是Mac 而是普通的笔记本,总幻想着拥有一台Mac,当然了这个愿望在13年10月份左右就实现了 Mac最大的 ...

  8. 第五节:什么导致Finalize方法被调用

    Finalize方法在垃圾回收结束时被调用,下面有5种事件会导致开始垃圾回收 1.第0代已满    第0代已满,垃圾回收会自动开始.该事件是目前导致Finalize方法被调用的最常见的一种方式,因为虽 ...

  9. 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果

    首先呢,还是一贯作风,我们先来看看众多应用中的示例:(这种效果是很常见的,可以说应用的必须品.)                搜狐客户端                               ...

随机推荐

  1. [POJ1068]Parencodings

    [POJ1068]Parencodings 试题描述 Let S = s1 s2...s2n be a well-formed string of parentheses. S can be enco ...

  2. Laravel5.1-错误和日志

    简介 这一章也是属于文档写得比较混乱的一章,所以我决定重新组织一下内容结构: 配置 debug配置 我们都知道,开发环境应该把debug打开,生产环境应该把debug关闭:这个设置在config/ap ...

  3. wor20161202

    http://wenku.baidu.com/link?url=tWdw-Kgn_Ncr52ooBSL2J0y_ZJy3SvAXGv9Lu5UOKB333frE48hmkQ_5Pj9CJeCtGm7_ ...

  4. 2016年11月3日--Window.document对象

    五.相关元素操作: var a = document.getElementById("id");找到a: var b = a.nextSibling,找a的下一个同辈元素,注意包含 ...

  5. nc 局域网聊天+文件传输(netcat)

    nc 局域网聊天+文件传输 nc的全程是netcat,这个工具非常好用. 有时候我们需要在局域网内传送一些文本消息或者文件的时候,通常的做法是安装一些局域网通讯软件,然后来做.其实不必要这样,使用nc ...

  6. 再谈Weiphp公众平台开发——1、成语接龙插件

    易错点,注意插件的命名 1.创建插件.在weiphp管理后台创建成语接龙插件,勾选安装后立即启用,不需要配置项和管理列表.点“确定”完成插件的创建. 2.安装插件. 3.检测插件是否成功安装.返回到w ...

  7. centos6.5 网卡的处理

    在centos安装后,找不到eth0/1 看了下dmesg | grep network的输出,发现不是驱动没有安装,而是重新命名了网卡. 1. 配置静态IP,修改 /etc/sysconfig/ne ...

  8. 【架构】Google的大规模集群管理工具Borg

    参考资料: http://www.cnblogs.com/YaoDD/p/5374393.html http://www.cnblogs.com/YaoDD/p/5351589.html

  9. ocket.chat 使用 Meteor 开发的实时协作工具,类似 丁丁。

    ocket.chat  使用 Meteor 开发的实时协作工具,类似 丁丁. https://rocket.chat/

  10. locustio压力测试

    2015年7月17日 22:19:17 星期五 这里记录下学习道路, 防止忘了 操作系统是centos: 首先是linux系统, 装有Python 和 Python-devel (否则安装软件会提示p ...