一、等值性——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. centos 修改DNS,网关,IP地址

    1.CentOS 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc/resolv.conf  修改以下内容 nameserver 8.8.8.8 #google域名服务器 nameser ...

  2. jQuery常用操作方法及常用函数总结

    一篇 jQuery 常用方法及函数的文章留存备忘. jQuery 常见操作实现方式 $("标签名") //取html元素 document.getElementsByTagName ...

  3. The Adapter of ListView: Just adapt data to view, don’t do anything else

    The design of SimpleAdapter is not good in my opinion. An adapter should just adapter the data to vi ...

  4. div元素抓取

    var files = $(".button").find("input[type='image']"); files.each(function() { $( ...

  5. python程序性能分析

    中文:http://www.cnblogs.com/zhouej/archive/2012/03/25/2379646.html 英文:https://www.huyng.com/posts/pyth ...

  6. apache2错误日志在哪,可以看到php错误

    在以下路径中 /var/log/apache2/error.log

  7. Android Studio (Gradle)编译错误

    Error:Execution failed for task ':app:processDebugResources' .com.android.ide.common.process.Process ...

  8. js数组转置

    <script type="text/javascript">     var arr=[[1,2,3],[4,5,6],[7,8,9],[17,18,19]];    ...

  9. nyoj_299_Matrix Power Series_矩阵快速幂

    Matrix Power Series 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 Given a n × n matrix A and a positive i ...

  10. imageNamed和imageWithContentsOfFile-无法加载图片的问题

    问题描述 图片资源放在Assets.xcassets中,分别用UIImage的类方法imageNamed和imageWithContentsOfFile获取图片对象,但发生奇怪的情况,前者获取到图片对 ...