Object中的公共方法解释:
公共方法:
Equals:
public class Object {
public virtual Boolean Equals(Object obj)
{
//如果两个引用指向同一个对象,他们肯定包含相同的值
if (this == obj) return true;
return false;
}
}
假设this和obj实例引用同一个对象,就返回true。似乎合理是因为Equals知道对象肯定包含和他自身一样的值。但假如实例引用不同对象,Equals就不肯定对象是否包含相同的值,所以就返回false。换言之,对于Object的Equals方法的默认实现,他是实现的实际是同一性,而非相等性。
Equals方法的正确实现:
1,如果obj实参为null,就返回false,因为调用非静态的Equals方法时,this所标识的当前对象显然不能为null
2,如果this和obj实参引用同一个对象,就返回true。在比较包含大量字段的对象时,这一步有助于提升性能
3,如果this和obj实参引用不同类型的对象,就返回false。一个string对象显然不等于一个FileStream对象
4,针对类型定义的每个字段,将this对象中的值与obj对象中的值进行比较,任何字段不相等,就返回false
5,调用基类的Equals方法来比较他的定义的任何字段,如果基类的Equals方法方法返回false,就返回false,否则就返回true
注:
同一性问题的测试使用Object的静态方法ReferenceEquals,其原型如下:
public static Boolean ReferenceEquals(Object objA, object objB)
{
return (objA==objB);
}
检查同一性问题(看两个引用是否指向同一个对象)务必调用ReferenceEquals,不应该使用C#的==操作符(除非先把两个操作数都转型为Object),因为某个操作数的类型可能重载了==符,为其赋值不同于同一性的语义。
System。ValueType(所有值类型 基类)都重写了Object的Equals方法,并进行了正确的实现来执行值的相等性检查(而不是同一性检查),ValueType的Equals内部实现如下:
1,如果obj实参为null,就返回false
2,如果this和obj实参引用不同类型的对象,就返回false
3,针对类型定义的每个实例字段,都将this对象中的值与obj对象中的值进行比较(而不是同一性检查)。ValueType的Equals内部的实现方式如下:
1,如果obj实参为null,就返回false
2,如果this和obj实参引用不同类型的对象,就返回false
3,针对类型定义的每个实例字段,都将this对象中的值与obj对象中的值进行比较(通过调用字段的equals方法),任何字段不相等,就返回false
4,返回true。ValueType的Equals方法不调用Object的Equals方法
在内部,ValueType的Equals方法利用反射完成上述步骤3,由于CLR反射机制慢,定义自己的值类型时应重写Equals方法来提供自己的实现,从而提高自己类型的实力进行相等性比较的性能,当然,自己的实现不调用base.Equals.
注:
定义自己的类型时,重写的Equals要符合相等性的4个特征
1,Equalse必须自反:x.Equals(x)肯定返回true
2,Equals必须对称:x.Equals(y)和y.Equals(x)返回值相同
3,Equals必须可传递:x.Equals(y)返回true,y.Equals(z)返回true,则x.Equals(z)肯定返回true
4,Equals必须一致。比较两个值不变,Equals返回值也不变
GetHashCode:
当你定义的类重写了Equals方法,还必须重写GetHashCode方法。之所以这样要求,是由于System.Collections.Hashtable类型,System.Collection.Generic.Dictionary类型以及其他一些集合的实现中,要求两个对象必须具有相同的哈希码才视为相等。所以重写Equals就必须重写GetHashCode确保相等性算法和对象哈希码算法一致性。简单点说就是,向集合中添加键/值对,首先要获取对象的哈希码。该哈希码指出键/值对要存储到那个哈希桶中。集合需要查找键时,会获取指定键对象的哈希码,该哈希码标识了现在要以顺序方式搜索的哈希桶,将在其中查找与指定键对象相等的键对象。采用这个算法来存储和查找键,意味着一旦修改了集合总的一个键对象,集合就再也找不到该对象。所以,需要修改哈希表中的键对象时,正确的做法是移除原来的键/值对,修改键对象,再将新的键/值对添加回哈希表。
自定义GetHashCode方法或许不是一件难事,但是取决已数据类型和数据的分布情况。下面会给出一个例子和规则:
internal sealed class Point
{
private readonly Int32 m_x, m_y;
public override int GetHashCode()
{
return m_x ^ m_y; //返回m_x和m_y的XOR结果
}
}
规则:
1,这个算法要提供良好的随机分布,使哈希表获得最佳性能
2,可在算法中调用积累的GetHashCode方法,并包含他的返回值。但一般不要调用Object或ValueType的GetHashCode方法,因为两者的实现都与高性能哈希算法不沾边
3,算法执行速度尽量快
4,包含相同值的不同对象应返回相同哈希值。例如,包含相同文本的两个string对象返回相同的哈希码
5, System.Object实现的GetHashCode方法对派生类型和其他的字段一无所知,所以返回一个在对象生存期保证不变的编号。
ToString:
默认返回类型的完整名称(this.GetType().FullName)
GetType:
返回从Type派生的一个类型的实例,指出调用GetType的那个对象时什么类型。返回的Type对象可以和反射类配合,获取与对象的类型有关的元数据信息。另外GetType是非虚方法,目的是防止类重写该fangfa,隐瞒企类型,进而破坏类型安全。
受保护方法:
MemberwiseClone:
这个非虚方法创建类的新实例,并阿静对象的实例字段设与this对象的实例字段完全一致。返回对新实例的引用。
Finalize:
在垃圾回收器判断对象作为垃圾被回收之后,在对象的内存被实际回收之前,会调用这个虚方法。需要在回收前执行清理工作的类型应重写该方法。
- NotSupportedException-无法将类型“System.DateTime”强制转换为类型“System.Object”
几张图就可以说明一切 2015-03-29 21:54:09,206 [77] ERROR log - System.NotSupportedException: 无法将类型“System.DateT ...
- 第4章 类型基础 -- 4.1 所有类型都从System.Object派生
4.1 所有类型都从System.Object派生 “运行时”要求每个类型最终都从System.Object类型派生. 由于所有类型最终都从System.Object派生,所以每个类型的每个对象都保证 ...
- 类型与通用语言运行时:System.Object
CLR 要求每个类型最终都要继承自 System.Object 类型 //隐式继承 Object class Employee { ... } //显示继承继承 Object class Employ ...
- C# 之 System.Object
System.Object C#中全部的类都直接或间接继承自System.Object类,这使得C#中的类得以单根继承.假设我们没有明白指定继承类,编译器缺省觉得该类继承自System.Obj ...
- 无法将类型“System.Nullable`1”强制转换为类型“System.Object”。LINQ to Entities 仅支持强制转换 EDM 基元或枚举类型。
在一个项目中使用LINQ和EF时出现了题目所示的异常,搜索了很多资料都找不到解决办法,主要是因为EF方面的知识欠缺. 先将情况记录如下,以供以后参考. 查询主要设计两张表,由外键关联: 在进行下面的查 ...
- C# System.Object基类
System.Object 基类 System.Object在.Net中是所有类型的基类,任何类型都直接或间接地继承自System.Object.没有指定基类的类型都默认继承于System.Objec ...
- The type 'System.Object' is defined in an assembly that is not referenced
记录一个错误,报 The type 'System.Object' is defined in an assembly that is not referenced,[System.Runtime] ...
- c# System.Object类和数据的安全转型
.NET Fraework 最重要的引用类型之一是System命名空间中Object类.所有的类都是System.Object的派生类.System.Object类型的变量System.Object的 ...
- System.Object
Object():System.Object类型的构造函数,自动调用. ~Object()/Finalize():System.Object类型的祈构函数,自动调用且不能够手动. Equals(obj ...
随机推荐
- Swift_语法的熟悉
Swift_语法的熟悉 oc与swift区变 文件区别oc有实现文件以及声明文件等,在swift中实现机声明类似文件总归结一个即可 1. 常量与变量的初始化 常量 关键字"let" ...
- C#将Excel数据表导入SQL数据库的两种方法(转)
最近用写个winform程序想用excel 文件导入数据库中,网上寻求办法,找到了这个经过尝试可以使用. 方法一: 实现在c#中可高效的将excel数据导入到sqlserver数据库中,很多人通过循环 ...
- 图片懒加载Demo
相关知识: [js获取元素位置+元素大小]全面总结
- 基于NIOS-II的示波器:PART4 系统调试&测试
本文记录了在NIOS II上实现示波器的第四部分. 本文主要包括:修改部分BUG,以及测试 本文所有的硬件以及工程参考来自魏坤示波仪,重新实现驱动并重构工程. version 1.0 界面修改& ...
- 发布一个Python小程序:ManHourCalendar
程序诞生的那些事儿 先聊聊背景资料档案.. 大约两年前,我只身前往岛国赚点外快.在那边的派遣制度工作中,存在一个大约叫每月的标准工作时间的概念,按照自家公司跟派遣目标公司(业界称为现场)的合同,规定了 ...
- Mac Intellij Debug 模式
前言:本文的核心是记录debug的使用,与具体的操作系统无关. 1.什么是Debug Debug是程序的一种运行模式.用来发掘程序的走向,以及程序在运行过程中参数的变化. 2.Debug的作用 deb ...
- 【2017集美大学1412软工实践_助教博客】团队作业3——需求改进&系统设计 成绩公示
第三次团队作业成绩公布 题目 团队作业3: 需求改进&系统设计 团队成绩 成绩公示如下: 缩写 TD BZ GJ CJ SI WBS GS JG DB SS SJ CS DC Total 分值 ...
- 201521123058 java第六次作业
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1.clone方法 1.1 Object对 ...
- 201521123075 《Java程序设计》第5周学习总结
1. 本周学习总结 2. 书面作业 作业参考文件下载 1 .代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分 ...
- 201521123002 《Java程序设计》第4周学习总结
[TOC] 1. 本周学习总结 2. 书面作业 1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) 参考文章 Eclipse添加注释简介 Ecli ...