• net框架通用对象操作


    一.对象的等值性和惟一性

     System.Object类型提供了一个Equals的虚方法,其目的为判断两个对象是否有个相同的"值".


    S/n?DfJvN0 1 class Object
    #bMT.W6WC]b0
     2     {ITPUB个人空间/q@+\%A qB
     3         public virtual Boolean Equals(Object obj)ITPUB个人空间*g)~"?eP
     4         {
    nSJYR+g2d0
     5             //如果两个引用指向的是同一个对象
    @h4c1m qW0
     6             //它们肯定相等
    9ffV|X)xm ] K0
     7             if(this==obj)ITPUB个人空间 {_9[FCLyau
     8             {
    6} He z _c3L1J]0
     9                 return (true);ITPUB个人空间0S?3t9|@l
    10             }
    *f+RO(f6L~ V0
    11 ITPUB个人空间 ~_CM,H7AbF
    12             return (false);ITPUB个人空间lq!z,H rc#I&l7\2Y
    13  
    .^5AOq k/kI0
    14         }ITPUB个人空间#d`#@ M2r {5uQ
    15     }

    这也许是最简单的方法.

    但有时间,它提供的默认实现对我们来说是不够的,必须重写Equals方法.

    自己写的时候,要遵循以下4条规则:

    1.Equals方法必须是自反的.也就是说,x.Equals(x)必须返回true.

    2.   Equals方法必须是对称的.也就是说,x.Equals(y)和y.Equals(x)必须返回同样的值.

    3.Equals方法必须是可传递的.也就是说,如果x.Equals(y)和y.Equals(z)都返回true,那么x.Equals(z)也必须返回     true.

    4. Equals方法必须是前后一致的.也就是说,如果两个对象的值没有发生变化,多次调用Equals方法的返回值应该相同.

    (一)为基类没有重写Object.Equals方法的引用类型实现Equals


    c Lo*r*y/n1u(E.M~0  class MyRefType:BaseType
    x!fH"{+g0    {
    |1Gn(H!|c,@0        RefType refobj;   
    //引用类型
    u{mE7A0
            ValueType valobj;  //值类型ITPUB个人空间#V%Dk FP P"T']
    ITPUB个人空间(St~7^&J ci
            
    public override bool Equals(object obj)ITPUB个人空间ya[.e dd,rP6R
            {ITPUB个人空间 d;u;T J@"N|i
                
    //因为‘this’不为null,所以如果obj为null
    | i0R*E"k3[3z9|'M1c0            
    //那么两个对象将不可能相等
    EdI*X'iaZ0
    ITPUB个人空间4T4DVp/[2\g
                
    if (obj == null)ITPUB个人空间 KL`;L3MUU
                    
    return false;
    Q2s+D}z'|0
    K`N!?[/di0            
    //如果两个对象的类型不同,那么它们不可能相等
    1{me YoqJ]0
                if (this.GetType() != obj.GetType())ITPUB个人空间3By$?cd+j
                    
    return false;
    (C%n `eP1Z0            
    //将obj转型为定义的类型以访问其中的字段,这里的ITPUB个人空间F'm4V/ciE{2z8K!r
                
    //转型不会失败,因为已经知道两个对象是同一类型
    0\v].U i&x[B0

    BB)hgY1Y'S0            MyRefType other
    =(MyRefType)obj;ITPUB个人空间~9O Lz;F%p&Vl!C

    ]NB@H@0            
    //比较其中的引用类型字段
    'TfkW m0
                if (!Object.Equals(refobj, other.refobj))ITPUB个人空间)bMe pENZ+W
                    
    return false;ITPUB个人空间4h WC;|5c0`$`G;Eu _
    ITPUB个人空间"_#u6B^ @h,?
                
    //比较其中的值类型字段
    :jc F9yCE:XXB0
                if (!valobj.Equals(other.valobj))
    G5I Hn,w0                
    return false;ITPUB个人空间n&s^ vGxW6|T

    he&K$t"ve}q0            
    return true;  //到这里两个对象才相等ITPUB个人空间i+vs5X3Q0j
            }ITPUB个人空间S.\ F$C*K|0~o
        }

    这要注意的:

    1.要比较引用类型的字段,我们应该调用Object的静态方法Equals方法.

        Objext的静态方法Equals方法是一个比较两个引用类型对象的辅助方法.采用这种方法比较,是因为即使两个字段出现了值为null的情况,代码仍会正常运行.

    2.要比较值类型的字段,应该调用该字段类型的Equals方法.不应该调用Object的静态方法Equals方法.因为值类型对象的值永远不可能为null,并且调用Object的静态方法Equals会对值类型对象执行装箱操作.

    (二)为基类重写了Object.Equals方法的引用类型实现Equals

     

    ITPUB个人空间t XH(dx$c0z^p
    class MyRefType:BaseType
    Z2nw2_;Q0    {ITPUB个人空间 u@3U,pv\
            RefType refobj;   
    //引用类型
    aQ+_4x%E"Hy0
            ValueType valobj;  //值类型
    m#|Gz8m5q.w]9^Kg0

    uA;X3iHJN0        
    public override bool Equals(object obj)ITPUB个人空间2keNRm,cJ{,z"V
            {ITPUB个人空间c*Z)pOIo&Dm
                
    //首先让基类型比较其中的字段
    BM`F5g0
                if (!base.Equals(obj))
    ywa RKzk-I0                
    return false;
    2Lq]S]0
    E \b)HvZ&i"O.iW#i0            
    //因为‘this’不为null,所以如果obj为nullITPUB个人空间 uf4LbE j
                
    //那么两个对象将不可能相等
    ,n5S T-W'\ MS0

    a"QHz3oi!rS&l0W/n0            
    if (obj == null)ITPUB个人空间q ZC!`:A
                    
    return false;
    H!w4\g[0
    &\3t_s_0P6ep0            
    //如果两个对象的类型不同,那么它们不可能相等
    8\$z4u[tC0
                if (this.GetType() != obj.GetType())
    2U0| YI&K~`#@+z_0                
    return false;ITPUB个人空间~"Yd%^&VE'x7S
                
    //将obj转型为定义的类型以访问其中的字段,这里的ITPUB个人空间9RAtX#Pk!\ L_:X%H9F!I
                
    //转型不会失败,因为已经知道两个对象是同一类型
    p&G;\ aS#p/w0
    ITPUB个人空间n,ze;Q x-i^%}
                MyRefType other
    =(MyRefType)obj;ITPUB个人空间N.F[,r0nb%^ n$T2Tk
    ITPUB个人空间&]RIN0B2P3G8[
                
    //比较其中的引用类型字段ITPUB个人空间/j,a8?/o9CQrkf
                if (!Object.Equals(refobj, other.refobj))
    vdD ]S6[ q0                
    return false;ITPUB个人空间HA*ng WeDc!^y

    ^W4Q_&M2ph r0            
    //比较其中的值类型字段ITPUB个人空间,{4C Eq O)a.fi
                if (!valobj.Equals(other.valobj))
    B.N,yH9@zLf2F0                
    return false;ITPUB个人空间;r7|#t+he,lT]x G
    ITPUB个人空间)mxn&|7d*\ \%n L3j
                
    return true;  //到这里两个对象才相等ITPUB个人空间H%_!s] g,v!X|
            }ITPUB个人空间K0v:v m^(e8p
        }

     

    如果调用base.Equals会导致调用Object.Equals方法,那么就不应该再调用它.这一点很重要.因为只有在两个引用指向同一个对象时,Object.Equals方法才会返回true.如果两个引用没有指向同一个对象,那么它将返回false.这样我们实现的Equals方法将总是返回false.

     当然,如果我们定义的类型直接继承自Object,我们就应该象第一段代码那样来实现Equals.如果我们定义的类型不是直接继承自Object,我们必须首先确定该类型的基类型是否重写了Equals方法.如果其中任何一个基类型重写了Equals方法,那么我们就应该象这段代码先base.Equals方法.



    作者:水木    
     
  • 相关阅读:
    在linux下搭建wiki环境【转】
    GitLab版本管理【转】
    linux设备驱动中的并发控制【转】
    分享三个USB抓包软件---Bus Hound,USBlyzer 和-USBTrace【转】
    Git常用命令总结【转】
    Linux中断(interrupt)子系统之一:中断系统基本原理【转】
    大话Linux内核中锁机制之原子操作、自旋锁【转】
    自旋锁spin_lock和raw_spin_lock【转】
    Linux内核同步机制之(四):spin lock【转】
    spin_lock浅析【转】
  • 原文地址:https://www.cnblogs.com/hsapphire/p/1646306.html
Copyright © 2020-2023  润新知