.Net框架程序设计-读书笔记(第六章 通用对象操作)

原创 2006年05月29日 11:22:00
1. 通用对象操作
1.1. 对象的等值性与唯一性
System.Object类型中的Equals方法实现:
class Object{
    public virtual Boolean Equals(Object obj){
        if ( this == obj )
            return true;
        return false;
    }
    public static Boolean Equals(Object objA, Object objB){
        if ( objA == objB )
            return true;
        if ( objA == null || objB == null )
            return false;
        return objA.Equals(objB);
    }
}
System.ValueType.Equals方法实现:
class ValueType {
    public override Boolean Equals(Object obj){
        if ( obj == null )
            return false;
        Type thisType = this.GetType();
        If ( thisType != obj.GetType() )
            Return false;
        FieldInfo[] fields = thisType.GetFields(BindingFlags.Public |
             BindingFlags.NonPublic | BindingFlags.Instance);
        for ( Int32 I = 0; I < fields.Length; i++ ){
            Object thisValue = fields[i].GetValue(this);
            Object thatValue = fields[i].GetValue(obj);
            If ( !Object.Equals(thisValue, thatValue) )
                Return false;
        }
        return true;
    }
}
1.       为基类没有重写Object.Equals方法的引用类型实现Equals方法
class MyRefType : BaseType{
    RefType refobj;
    ValType valobj;
    public override Boolean Equals(Object obj){
        if ( obj == null )
            return false;
        if ( this.GetType() != obj.GetType() )
           return false;
        MyRefType other = (MyRefType)obj;
        if ( !Object.Equals(refobj, other.refobj) )
            return false;
        if ( !valobj.Equals(other.valobj) )
            return false;
        return true;
    }
    public static Boolean operator==(MyRefType o1, MyRefType o2){
        return Object.Equals(o1, o2);
    public static Boolean operator!=(MyRefType o1, MyRefType o2){
        return !(o1 == o2);
}
2.       为基类重写了Object.Equals方法的引用类型实现Equals方法
class MyRefType : BaseType{
    RefType refobj;
    ValType valobj;
    public override Boolean Equals(Object obj){
        if ( !base.Equals(obj) )
            return false;
        if ( obj == null )
            return false;
        if ( this.GetType() != obj.GetType() )
            return false;
        MyRefType other = (MyRefType)obj;
        if ( !Object.Equals(refobj, other.refobj) )
            return false;
        if ( !valobj.Equals(other.valobj) )
            return false;
        return true;
    }
    public static Boolean operator==(MyRefType o1, MyRefType o2){
        return Object.Equals(o1, o2);
    public static Boolean operator!=(MyRefType o1, MyRefType o2){
        return !(o1 == o2);
}
如果调用base.Equals会导致调用Object.Equals方法,那么就不应该再调用它。因为Object.Equals方法只有在两个对象指向同一个对象时才会返回true。
如果定义的类型直接继承自Object,应该采用第一种方式。如果定义的类型不是直接继承自Object,首先确定该类型的基类型(除Object之外)是否重新了Equals方法,如果没有任何基类重写Equals方法,则采用第一中方式,否则采用第二种方式。
3.       为值类型实现Equals方法
struct MyValType{
    RefType refobj;
    ValType valobj;
    public override Boolean Equals(Object obj){
        If ( !obj is MyValType) )
            Return false;
        Return this.Equals((MyValType)obj);
    }
    public override Boolean Equals(MyValType obj){
        If ( Object.Equals(this.refobj, obj.refobj) )
            Return false;
        If ( this.valobj.Equals(obj.valobj) )
            Return false;
        Return true;
    }
    public static Boolean operator==( MyValType o1, MyValType o2){
        return Object.Equals(o1, o2);
    public static Boolean operator!=( MyValType o1, MyValType o2){
        return !(o1 == o2);
}
对于值类型应该为它定义一个强类型版本的Equals方法,让其接受定义类型作为参数。但是如果MyValType和别的类型之间定义了隐式转换,它们将有可能被判为相等,而它们的类型却不相同。
在上面接受Object参数的Equals方法中,使用is操作符来检查obj的类型。这里使用is而不使用GetType是因为在值类型实例上调用GetType会导致装箱。而前面引用类型MyRefType的Equals实现,则只能使用GetType方法,而不能使用is操作符。因为is操作符在判断一个对象与它的任何一个基类型之间的关系时都会返回true。
4.       对象唯一性识别
class Object{
    public static Boolean ReferenceEquals(Object objA, Object objB){
        return (objA == objB);
}
当C#编译器看到使用==操作符来比较两个类型为Object的引用时,编译器会产生比较两个对象引用是否相同的IL代码。
编译时类型又称声明类型、静态类型,是代码中显式声明的类型。运行时类型又称实际类型、动态类型,是变量所引用的对象的真实类型。GetType方法返回的是运行时类型。
1.2. 对象的散列码
一个类型必须同时重写Equals方法和GetHashCode方法,因为System.Collections.Hashtable类型的实现要求任何两个相等的对象都必须有相同的散列码。
1.3. 对象克隆
浅拷贝(shallow copy)是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。而深拷贝(deep copy)是对对象实例中字段引用的对象也进行拷贝的一种方式。
Object.MemberwiseClone方法实现:
1)       为新对象分配内存;
2)       遍历类型中的所有实例字段,并将原对象中所有的位拷贝到新对象中;
MemberwiseClone不会为新对象调用构造器,而只是保证它的状态和原对象一致。

《.NET框架程序设计》第六章 通用对象操作

一、对象的唯一性识别:即判断两个引用是否指向了同一个对象?可以使用”= =” 操作符来比较两个引用,也可以使用System.Object的ReferenceEquals的静态方法。 二、对象的散列码:...
  • Ninth
  • Ninth
  • 2004年09月02日 20:10
  • 2469

【读书笔记】《Effective Java》(7)--通用程序设计

由至周末,再更新一章的笔记,做到后来发现,78条建议只读标题可以都懂一些东西,再都每一条里面的例子又是另外一些知识。...
  • lqadam
  • lqadam
  • 2016年09月24日 16:22
  • 392

终于把Microsoft .NET框架程序设计(修订版)看完了

这本书是由windows & .Net专家Jeffrey Richter写的,现在最新的是第二版CLR Via C#。虽然内容差不了多少,不过俺还是买了。:D。此书由李建忠老师翻译的。   Jeff...
  • kisserLeon
  • kisserLeon
  • 2006年11月28日 19:09
  • 1867

.NET框架程序设计——体系结构

谈到.NET,相信对于大多数初学者而言,都会感觉比较乱、比较迷茫,什么ASP.NET、VB.NET、VC.NET、ADO.NET、.NETFramework 等等概念,搞的我们晕头转向的,他们之间到底...
  • dongyue786
  • dongyue786
  • 2014年10月15日 15:47
  • 1982

快学Scala习题解答—第六章 对象

6 对象  6.1 编写一个Conversions对象,加入inchesToCentimeters,gallonsToLiters和milesToKilometers方法  Scala代码   ...
  • u012762573
  • u012762573
  • 2015年08月20日 16:08
  • 975

java程序设计基础_陈国君版第五版_第六章习题

java程序设计基础_陈国君版第五版_第六章习题class Student{ int ID; String name; String sex; boolean leader; float g...
  • gaoenbin626
  • gaoenbin626
  • 2016年03月09日 10:27
  • 3152

.net框架程序设计读书笔记二(Microsoft .net 框架开发平台体系架构)

第一章:Microsoft .net 框架开发平台体系架构    本章的目标:对.net框架体系架构有一个总体的认识,并对.net框架中出现的一些新的技术和术语有一个基本的了解。 1.1 将源代码编译...
  • cwbboy
  • cwbboy
  • 2004年05月31日 16:57
  • 996

前言[《.net框架程序设计》读书笔记]

  • zgqtxwd
  • zgqtxwd
  • 2008年04月24日 08:56
  • 143

关于《.net框架程序设计》读书笔记

  • zgqtxwd
  • zgqtxwd
  • 2008年04月24日 08:58
  • 101

.net框架程序设计读书笔记系列

2004.7.15 [C#学习记录]使用C#编写一个自定义控件(高手莫入,哈哈)     griefforyou [原作] using System;using System.Collections...
  • newmankind
  • newmankind
  • 2004年06月30日 17:37
  • 546
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.Net框架程序设计-读书笔记(第六章 通用对象操作)
举报原因:
原因补充:

(最多只允许输入30个字)