设为首页收藏本站|繁體中文 快速切换版块

 找回密码
 立即加入
搜索
查看: 1074|回复: 0

C#的==运算符和Equals()方法区别

[复制链接]
  • TA的每日心情
    慵懒
    2016-4-21 12:07
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    累计签到:3 天
    连续签到:1 天
    发表于 2010-5-10 08:24:45 | 显示全部楼层 |阅读模式

    马上加入,结交更多好友,共享更多资料,让你轻松玩转电力研学社区!

    您需要 登录 才可以下载或查看,没有账号?立即加入

    ×
    using System;
    + K9 [+ B  R' }/ Nusing System.Collections.Generic;
    . b' e+ U1 E3 i( Lusing System.Text;+ P$ D2 a: i: M! {  o
    namespace ConsoleApplication1
    $ W( k: G  {+ ]& n6 z7 r* x{
    9 c6 s# B" C7 C6 z0 n$ h    class Person
    3 D/ M' D6 n5 y( E- r    {
    # k7 b' T  M7 P0 ]: ~        private string name;' s0 G. P: s2 v3 Z2 [1 A, v  T* ]% {
            public string Name+ _5 L6 U0 a' w0 U, E0 x' z7 D
            {% ~( }- a+ }2 J5 ]
                get { return name; }
    & Q5 @: }! s9 g' F9 Y            set { name = value; }
    % t' M9 v9 R( r* V& H* @1 i1 h! ^        }
    7 g) D7 m+ {. f
    , D- ^3 f, d3 |: o1 [* T$ l) e. H% b/ b        public Person(string name)( S$ q1 _) n0 l# y
            {
    / m/ \# V- P/ a2 o* d3 `% U, ~8 @9 V            this.name = name;
    , T- B5 M8 X. ]2 k( Z        }
    $ b, {& |. v7 r% O" F    }
    . b$ i0 p# F! _3 a6 g/ Q    class Program$ v* d' D$ p! p$ G% c
        {
    3 S) Z# n% A5 F3 U4 l( E. r. O        static void Main(string[] args)8 N; }8 j  A$ {- \4 h7 I0 P
            {, `  `1 [1 O8 X5 o! R1 r; O. L. ^
                string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });) q; c6 d* n$ k9 R' C4 y" S% p1 u6 F
                string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
      D3 X. V0 e4 K7 M" D, B7 m( M            Console.WriteLine(a == b);
    % q. l) v  O1 I: R& E/ z- U  b            Console.WriteLine(a.Equals(b));2 ~2 V, P+ P/ ^* }
                object g = a;
    , c) b4 W4 s! u8 X: ^5 H1 y            object h = b;8 |6 i# c: W/ r5 A  }
                Console.WriteLine(g == h);
    ) Y6 T) H# ?* T- S1 g3 N            Console.WriteLine(g.Equals(h));
    " I; O( S% r! E# f( T            Person p1 = new Person("jia");; _: s) i% ^$ `0 W
                Person p2 = new Person("jia");
    - j: h( M2 f) {6 i1 c- p. t3 a            Console.WriteLine(p1 == p2);
    - V% Z: l9 I- Y1 k            Console.WriteLine(p1.Equals(p2));
    * q% ^- c  L8 K6 x            Person p3 = new Person("jia");
    ! P6 ]* }' x$ j% x6 p            Person p4 = p3;) b7 ~* f+ Y% v3 \; r8 c* r4 B4 h- A
                Console.WriteLine(p3 == p4);
    & f, ]: D$ O8 Z& i. g            Console.WriteLine(p3.Equals(p4));
    / d8 x3 x+ \3 o; ?# C( n            Console.ReadLine();
    / Q2 g8 u% J- Q( Z# s: @        }- x, U( k6 U6 Y
        }* J* [; L1 ]) e4 E/ i. _0 |# o
    }
    5 m0 V8 ~- f  T# E. s5 X( @; i+ U答案为何为true true false true  false false true true" q9 y* H' E% s8 c) w% H. E
    因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。, p% q, r: U6 v! ]( R# j
      "==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
    2 B6 S6 z, k0 b# W9 c" U  "equals" : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。" x* E% R. k' c) _3 R" I. h* y
        而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。7 M5 E& f3 _" }8 R5 t: n
        因此在上面的例子中,第一对输出 ,字符串a和字符串b的两个比较是相等的。! H* o% W+ ?5 {6 A
        对于 第二对输出 object g = a 和object h = b ,  在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:8 T5 H' Z' G8 `( ?1 H% g
            string a="aa";
    8 ?# E* Z7 r" |3 R, Q* ]% ~        string b="aa";, F- E/ e9 `+ \+ M, _1 X
    则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
    5 }9 f. A' u9 h( o7 c- Q! D) B对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。2 `3 F% a% h- I
    对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。
    2 _* C  G+ S3 S8 p7 V$ R& k  zMSDN中就有介绍啊:; d2 c. g  f! p; V4 u
    下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:
    ; W( {# C5 w9 L& H1 u5 ]每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。; k" k: O4 T' g& ?4 H; f( {7 B" C
    每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。
    / Q: Y4 H+ v% g9 V. J4 K每次实现 IComparable 时都要重写 Equals 方法。
    8 [! d" v9 o# O. a5 V( B9 |实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载。
    6 I- O% w8 s- H8 }( B3 I不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。2 D, L8 @% _3 y7 |6 z! H3 R
    有关 Equals 方法的相关信息,请参见实现 Equals 方法。: i  f, S$ G  c9 t
    在值类型中实现相等运算符 (==)
    " c* m4 N& p" r! U" v大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。
    ) @; j" M0 s, Z( j应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。8 f8 ~0 c; }3 \) ]
    每次重写 Equals 方法时都实现相等运算符 (==)。. ]9 F* I1 K' U1 `, V
    在引用类型中实现相等运算符 (==)
    : W0 c0 ^4 z5 K6 z4 \$ z大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。
    # I8 \. y5 S/ y如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。
    & N. y4 \# i+ s$ \4 J; _( D好了,下面是考题,相信答案大家都知道了。
    6 n" R& a( x5 ~/ @5 W            Console.WriteLine((2 + 2) == 4);
    ) v4 s) L6 G, v1 `- N$ x2 P# j: g- y            object s = 1;
    ! T1 W' A. Y0 d7 O            object t = 1;0 }% O# N& _+ k. z. u% {8 Q) R% }, ?4 a
                Console.WriteLine(s == t);
    9 F  i, N5 M/ w+ p  M            string a = "hello";4 W' Y0 L2 C- o' @' g
                string b = String.Copy(a);
    # J; b+ u# D; T" I6 z1 c            string c = "hello";
    ' [8 s0 c! [8 y( d            Console.WriteLine(a == b);" o8 s, L/ I* Y  H. n
                Console.WriteLine((object)a == (object)b);
    . C. L- S7 d" L! L# F7 m            Console.WriteLine((object)a == (object)c);
    & w0 V- K0 Z8 d答案:TRUE, FALSE, TRUE, FALSE, TRUE
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

    小黑屋|手机版|APP下载(beta)|Archiver|电力研学网 ( 赣ICP备12000811号-1|赣公网安备36040302000210号 )|网站地图

    GMT+8, 2026-10-10 08:33

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表