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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    using System;
    6 u: m: F& h! E8 I) Nusing System.Collections.Generic;$ q3 X: v, Z8 ~) @1 Z, ^- U9 j
    using System.Text;
    / o5 f/ }6 F' j1 i; rnamespace ConsoleApplication1
    7 x9 k: g7 `. @' _6 n- y( i- o{: M% w* \1 ?. o+ @9 z$ ^( n. q. Q
        class Person
    1 E  j( V& a, x9 F/ A: G$ d    {) a. d0 U- D! C( }9 m3 a3 O
            private string name;
    5 P  ~! i- ~" p" W7 Q! J        public string Name
    ; \, T- I$ t& K: W; H% G        {/ x+ b# e. _+ n4 n0 L9 k
                get { return name; }
    - E( \+ r( I& j4 p            set { name = value; }
    4 k: S. k* J9 q1 d% S        }5 k! h+ X$ Q% e+ b
    3 [- N4 @$ `+ O2 X% ^2 R2 D+ i* D
            public Person(string name)
    7 `/ |7 X, {" u: W, j4 y, Y5 _        {8 {& q& }9 s& f$ U5 F* h7 X
                this.name = name;5 A# w0 S+ s% h1 ^+ |
            }
    8 a: Q! z2 ~9 C7 H; l2 o8 Q9 v( h% I    }# [# Z8 @, O8 {. s7 [! m
        class Program
    ' Y; E  K" Q! E4 o9 a    {3 l2 i/ q, o! o8 S
            static void Main(string[] args)
    : D; l  o5 G- W2 X, X) e! y3 N        {& E: @" h( a* n4 K5 {
                string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
    # N$ u4 {5 _" A% x4 j            string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });) S. c/ X9 H' Y+ U' v1 T. `9 t7 i
                Console.WriteLine(a == b);- ?& G" `0 ]/ n# r2 _
                Console.WriteLine(a.Equals(b));
    7 f5 n# J' c6 Q. n: A9 [0 ]            object g = a;
    ! K" D7 z  J+ {. j            object h = b;/ [" B8 ]3 L2 E# f! `4 R. I. K: K, L
                Console.WriteLine(g == h);- _  A3 G& @6 [- Y
                Console.WriteLine(g.Equals(h));
      ^+ J; X5 k6 x            Person p1 = new Person("jia");
    ' i4 S( I& a1 P            Person p2 = new Person("jia");
    8 U7 {) r' J6 _            Console.WriteLine(p1 == p2);
    # J6 D" T& g! V+ @! g6 z  {            Console.WriteLine(p1.Equals(p2));
    ( p/ R3 H& y# Q4 O5 K            Person p3 = new Person("jia");
    ! K, |" w' W) {            Person p4 = p3;$ K$ t' b1 e" W, o, N0 E
                Console.WriteLine(p3 == p4);
    % r8 J2 n( F. I4 H: |, s            Console.WriteLine(p3.Equals(p4));. t3 v4 B6 _+ _, q9 C
                Console.ReadLine();
    4 J( m, c3 K/ s: z+ i, \        }
    1 y% S0 x: n+ G+ f2 l- D    }1 l6 i% Q% E8 Z4 w# H: m
    }( d8 C  r. P# s3 m9 ~( N+ I# b
    答案为何为true true false true  false false true true
    & u+ E: j( ?3 B& g+ X- V因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。4 ?+ @9 N2 @- _
      "==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
    6 {2 A: p0 c# Z  S# d# m! r, t  "equals" : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。+ ^! W6 X3 j2 h9 V) b0 h7 W$ [& X
        而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。
    / [  G0 |0 }( e. _    因此在上面的例子中,第一对输出 ,字符串a和字符串b的两个比较是相等的。# m0 }. x3 b- G  l4 O
        对于 第二对输出 object g = a 和object h = b ,  在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:
    ) g8 _7 S7 q; Y) D8 K        string a="aa";
    ! h# k& M6 t: G5 R% t        string b="aa";' G: F0 w0 `: m1 {
    则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
    5 k$ }& `1 m: p; m& t! ?对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
    - o0 M9 q" n( W$ Y  s2 Y8 k对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。2 ?2 @+ k1 e6 ?' ]) `+ O3 d) R
    MSDN中就有介绍啊:
    $ Z8 h; i2 s% q下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:9 x) H& E, [$ I$ k  ]
    每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。
    - S2 ]: X+ |& n3 }; G1 N, f! A每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。
    8 q9 S# C. q- f3 N& h每次实现 IComparable 时都要重写 Equals 方法。
    : X2 _' W) H" ?9 d8 m" `实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载。# s( c# E/ ?+ X" {, `* E
    不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。1 f! O& [) _/ Z0 e: c
    有关 Equals 方法的相关信息,请参见实现 Equals 方法。3 R6 x( Y0 p2 W; i
    在值类型中实现相等运算符 (==)
    7 `) _- H( K& `  m2 |大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。
    % F  q' b, w( N应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。
    ; ^( d4 {9 {% e# s, t6 f3 C4 ~1 ^每次重写 Equals 方法时都实现相等运算符 (==)。# b; y! j. @# k6 V
    在引用类型中实现相等运算符 (==)
    ' c$ a+ R/ u6 O% j. E& C( R: L大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。
    ! E8 O9 z# f! B  d3 H( S) S* P/ y7 J( z如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。* f- I/ O/ N/ N- r- _
    好了,下面是考题,相信答案大家都知道了。
    ' ~1 m1 p) E- Y1 `8 ?: J7 p, [            Console.WriteLine((2 + 2) == 4);! z% P+ D' f; _, K- C# S6 r4 R
                object s = 1;
    # H. M9 v7 G( _0 Q0 r" @            object t = 1;
    1 I0 b+ v: ~( E, |            Console.WriteLine(s == t);& q6 c" K$ H0 ^$ Q" g3 b8 ?
                string a = "hello";
    4 }3 w+ K: _- H% ?* g2 x. Q            string b = String.Copy(a);* A8 N  e0 u& B2 a& H
                string c = "hello";( R. ]# c2 l6 O
                Console.WriteLine(a == b);7 d( N- m" @3 p! N1 s! X9 Q2 h+ O/ D
                Console.WriteLine((object)a == (object)b);
    6 S+ @8 m9 g$ ?! i# H' S            Console.WriteLine((object)a == (object)c);
    : J4 L9 D6 r: e2 m. S答案:TRUE, FALSE, TRUE, FALSE, TRUE
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-3-19 08:06

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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