.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不会为新对象调用构造器,而只是保证它的状态和原对象一致。

相关文章推荐

Microsoft .NET框架程序设计读书笔记(一)

1.什么是DLL hell?由什么引起的? DLL hell DLL灾难是由COM组件升级引起程序不能运行的情况。COM对象常常编译为dll文件。由于COM对象可以重用,这样多个程序可能使用同一...

学习《.net框架 程序设计》学习笔记---委托(一)

一.认识委托      在.net框架中,回调函数任然像在非托管windows编程中一样有用和普遍。但是,.net框架为回调函数提供了一种称为委托(delegate)的类型安全的机制。      例如...

《.NET框架程序设计(修订版)》--第三章 共享程序集 (1) 转载

学习笔记《.NET框架程序设计(修订版)》--第三章 共享程序集 (1)2004-12-27第二章里讲到对程序集的私有部署方式。这章里探讨创建可以被多个应用程序共同访问的程序集,即全局部署程序集(gl...

JavaScript高级程序设计(第3版)第六章读书笔记

第六章 面向对象的程序设计 1. 数据属性 [[Configurable]]:表示能否通过delete删除属性从而重新定义属性。默认值为true。 [[Enumerable]]:表示能否通过for-i...

JavaScript高级程序设计读书笔记(第六章)(四)

组合使用构造函数模式和原型模式
  • xqnode
  • xqnode
  • 2017年02月13日 22:13
  • 104

JavaScript高级程序设计读书笔记(第六章)(三)

原型模式
  • xqnode
  • xqnode
  • 2017年02月12日 23:19
  • 89

JavaScript高级程序设计读书笔记(第六章)(五)

寄生组合式继承
  • xqnode
  • xqnode
  • 2017年02月13日 22:18
  • 81

JavaScript高级程序设计读书笔记(第六章)(二)

工厂模式,构造函数模式和原型模式
  • xqnode
  • xqnode
  • 2017年02月12日 20:55
  • 140

《lua程序设计》读书笔记 第六章:深入函数

在Lua中,函数是一种“第一类值”,它们具有特定的词法域。“词法域”是什么意思呢?这是指一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数中的变量。 在Lua中有一个容易混淆的概念是,函数与...

JavaScript高级程序设计读书笔记(第六章)(一)

对象的属性类型
  • xqnode
  • xqnode
  • 2017年02月12日 20:29
  • 96
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.Net框架程序设计-读书笔记(第六章 通用对象操作)
举报原因:
原因补充:

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