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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    using System;
    ; o- P. ^! m+ l4 U  e) W( Nusing System.Collections.Generic;" K" G3 C  M5 v  m
    using System.Text;, _3 z$ u* ~% g) m$ b
    namespace ConsoleApplication1
    7 e' d6 f) C! Z8 c' |, z* t; G' F{, X- D# b2 y9 @1 ~
        class Person
    3 i) b" |/ ], R2 {7 o9 t6 n    {0 f0 W6 K2 N  b5 [: Z
            private string name;
    . p& k5 C0 C1 T0 i/ F4 W5 M% z        public string Name
    ( i0 V: \9 K+ B8 ~: K5 d7 L        {
    0 y5 |& O: S" R( e( M3 I6 [3 C& o+ g7 B            get { return name; }: i- s% r+ N) O; N- j
                set { name = value; }8 G/ ^3 G: ~2 c; U5 G9 `4 l
            }
    5 w# h: n7 k/ Z! a8 O5 m/ c
    ) |! ~" [% a& z" G) N        public Person(string name)
    ) n5 ~6 i2 P% z: t* d# Y- M        {
    * }  V: L! J: ?4 z  o            this.name = name;
    ) Y0 a; U% n+ `4 H) V+ O2 P1 Q# j        }$ J0 m: {3 [" Q1 T. [
        }  \3 ~4 N7 b& d3 g4 s8 ]
        class Program% J, Y( D. U$ H) N! U5 Q1 u
        {
      W, v2 b& i9 i3 A' A9 o- ]' L) o/ I        static void Main(string[] args)
    ; e( o* Z; F! u: B        {
    . R% D: A5 O! v) a1 t            string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });) P1 f4 s' @7 Q
                string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
    3 O1 {: [2 I) I- q            Console.WriteLine(a == b);4 n* Q* ]% G+ T6 l' p7 H
                Console.WriteLine(a.Equals(b));
    ! K7 K$ z& F9 ]4 N            object g = a;# s5 l- G0 `1 g& p% s
                object h = b;* y; w) a% s2 B( t
                Console.WriteLine(g == h);
    8 j) \* e$ v- d* @  {            Console.WriteLine(g.Equals(h));
    & L, V5 r0 \4 c) t9 R0 Q/ K2 U/ ?            Person p1 = new Person("jia");
    4 Z4 p8 a+ R" K1 `4 w% O            Person p2 = new Person("jia");
    . J) d4 c: l  ~) l6 ?* o7 D7 D            Console.WriteLine(p1 == p2);2 h' n1 I- X* s# M2 v* `' k
                Console.WriteLine(p1.Equals(p2));) X6 n5 J7 Y2 E
                Person p3 = new Person("jia");
    , Q9 {( r' i$ }2 e& T) n2 |            Person p4 = p3;
    6 Y, N# C6 B( S( i            Console.WriteLine(p3 == p4);
    ) @6 X0 x) {) _, @) `            Console.WriteLine(p3.Equals(p4));/ {0 Q/ V" L" C8 J" g" Y) d* Y) X
                Console.ReadLine();! `- ^0 k  n: w1 m" y
            }
    0 u/ I" d! a7 N+ z, D    }' i& \+ {7 e% ?3 }1 E. ~. k
    }; d  }. \" S# X# l
    答案为何为true true false true  false false true true
    ! i; `) E- j4 I( T因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
    . V; W( H( s, F% i  "==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
    . r7 E1 I# B3 d  M" h% P1 O4 j  "equals" : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
    8 F2 I% `: K7 B/ ]    而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。
    4 @% A7 x/ R* ~% o4 m5 F) d, Q    因此在上面的例子中,第一对输出 ,字符串a和字符串b的两个比较是相等的。
    / A0 h, t& r; ]2 Y# `& c7 G    对于 第二对输出 object g = a 和object h = b ,  在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:( _  q  O, [- r) N: ]% r+ ^5 E
            string a="aa";
    ( D. e! x& x7 J* G, o" Q1 b6 f; u* }6 _        string b="aa";# w, ~- Y( S7 L
    则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
    , _  ?0 G$ v9 n7 X& Z1 {( ^对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
    ' T; ]1 w2 {; c对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。# [2 ]! X; p$ K' z( q, Q( l
    MSDN中就有介绍啊:
    6 S" Z0 r" x- c1 f' A下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:
    3 Y& F! r  G4 W" H每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。
    & Y/ Y! ]% ^9 ~  D0 F每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。" W1 Q7 j3 P$ I) E7 z7 K
    每次实现 IComparable 时都要重写 Equals 方法。
    # l. O  y/ C' k实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载。; u1 }) q- }* G. H3 v
    不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。1 N* r9 _3 ]7 j$ {
    有关 Equals 方法的相关信息,请参见实现 Equals 方法。- i& ]% L' Q2 u$ r! X
    在值类型中实现相等运算符 (==)4 U/ y8 k& G1 y1 L% Z& P3 F, D; Q( P
    大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。: \! m+ L/ U* F9 L/ {( B- d
    应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。
    - X5 R& V; R6 _每次重写 Equals 方法时都实现相等运算符 (==)。3 B0 Y$ }# x3 l" v; ]( d$ ~7 @6 s+ i
    在引用类型中实现相等运算符 (==)
    5 n) o* t% h/ ?. B大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。+ r# R" d+ ]8 }4 m
    如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。: t8 L% S8 H3 N! w4 K
    好了,下面是考题,相信答案大家都知道了。
    # J4 s% h* R, L' a0 F            Console.WriteLine((2 + 2) == 4);1 Z2 W6 \( P) K7 e# }) O
                object s = 1;: l5 {4 c  ]0 R+ Y4 ?
                object t = 1;5 q$ r5 e7 v; m- P# ^
                Console.WriteLine(s == t);
    6 u) S! O# b# M' w            string a = "hello";# t. {4 m, K& m- B! {/ [
                string b = String.Copy(a);
    - L* M/ |; [" o: K. S+ |# J' N8 E            string c = "hello";. M7 b2 F. R3 X* H
                Console.WriteLine(a == b);; x$ F- k8 j. w/ Q: g1 r& Y
                Console.WriteLine((object)a == (object)b);7 T7 n  R0 y4 T# x. ~
                Console.WriteLine((object)a == (object)c);
    2 e! |7 ?: {  z+ i: J' S% G答案:TRUE, FALSE, TRUE, FALSE, TRUE
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-3-18 12:35

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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