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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    using System;4 |# ?" z% l; F& v! q" m( u, z! ?
    using System.Collections.Generic;0 G8 I7 m" Q3 d( v- g% z8 ]# k
    using System.Text;
    5 L9 |7 c. ^" `$ Ynamespace ConsoleApplication18 O: J$ A; G# M4 f: f' Q4 q
    {
    # i. z# ?2 q4 C+ w    class Person8 f: n. Y" K  b. }; N5 @
        {
    % `6 O0 y5 n  t- s. ~; m        private string name;
    & j, K4 H( s. F6 [        public string Name
    2 i" r& u1 Y+ n) h$ g; X        {% {9 ?  \4 O$ E" B+ @
                get { return name; }' Z# @2 v) f# R
                set { name = value; }/ ?# P/ c; y. V& w3 B
            }, v/ M% J3 v% j- {3 X
      s2 b$ _  x: x9 }0 n, _6 e
            public Person(string name)
    ( {0 K( ?( x2 B8 j; O; h* Y/ b. p  i) f        {3 b/ ?( V# O$ O1 k2 t0 S
                this.name = name;
    / Q: Q0 p  M" H4 u  N        }/ p7 g+ D; y" x$ E+ i6 {
        }+ X: C& V. M, S- n/ K  ~
        class Program
    " H7 ]2 Z% I* u7 g! H) T% x) b    {
    3 Y1 X! l9 @8 R. Q        static void Main(string[] args)
    ( w1 d2 |7 N" m" p. b9 E* X9 p1 K% `- E        {
    ; z. |# ]% ?4 T7 Z6 Y            string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });) @% Q; S/ Q2 y! b
                string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });- O& }  _- ~; [" i  G/ {
                Console.WriteLine(a == b);
    5 s- H' k4 G# t# t3 P$ V* T            Console.WriteLine(a.Equals(b));7 p5 f4 l1 m% w9 O
                object g = a;
    ; Y8 L  l, R, D  S3 |, G  q            object h = b;5 i7 s( g7 ]% j
                Console.WriteLine(g == h);4 W0 |7 `& W' C& W# \- D/ L
                Console.WriteLine(g.Equals(h));( _3 r7 q1 U7 J2 x, A/ j- ^  E8 H3 L% Y
                Person p1 = new Person("jia");
    " I/ k. v* z* h% }9 l            Person p2 = new Person("jia");* x3 Q. H5 r9 R+ s. ?! E
                Console.WriteLine(p1 == p2);% d+ u5 x$ \' f8 u5 M0 c/ o3 [/ g
                Console.WriteLine(p1.Equals(p2));, f7 y) B) E" z* ?& o& E/ m
                Person p3 = new Person("jia");
    ) z* M. [: p9 ~2 h! V$ I, }            Person p4 = p3;
    5 j5 e: T$ s/ F9 ~7 O            Console.WriteLine(p3 == p4);
    : i/ {8 N; g# l; y- S            Console.WriteLine(p3.Equals(p4));- o6 i; ]1 `' F( ]. F
                Console.ReadLine();( v  G# c1 e9 ?& v5 P! L
            }
    9 C9 K$ v  I  S+ A8 J3 ~! @$ d    }
      ~3 M' }  d/ Z}
    ; s3 y" k7 I5 y8 v答案为何为true true false true  false false true true
    - a$ |* j" J6 o! C  @, f5 n因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
    , c; y8 ^) N5 r  "==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。+ S6 i  N# F2 J; |# A: J/ m: |6 [
      "equals" : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
    3 d% z3 Y  F' y    而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。8 f, ~* j) r$ a. ?6 K& G' o! h
        因此在上面的例子中,第一对输出 ,字符串a和字符串b的两个比较是相等的。+ ]3 A8 R& m2 `/ o8 V
        对于 第二对输出 object g = a 和object h = b ,  在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:' N; ~" K* N3 C7 z7 Y$ J& B
            string a="aa";$ [( O: s+ T1 G- M$ m2 c. j5 V
            string b="aa";
    # c/ B- U7 M, z* G7 ?则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。0 j, v' R2 F/ V0 ^$ ^
    对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。! z' M8 G  K2 N; f# M/ u! P
    对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。
    ' W' j9 B0 n! @1 Y4 iMSDN中就有介绍啊:( S0 s/ x  r/ V8 O; @
    下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:3 Z2 o! E( ~: U. s, }% x3 ^- }
    每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。- |/ y4 b, u5 a
    每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。6 L6 S/ Z* d: ^1 }2 @  p
    每次实现 IComparable 时都要重写 Equals 方法。. B  y& N  ^5 J% q5 c! e& }7 J" K
    实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载。+ ?+ Q8 M' W1 \0 t& _1 ?: V' {  A, G
    不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。
    1 G7 ?& F- S1 T# e6 @有关 Equals 方法的相关信息,请参见实现 Equals 方法。1 T! k6 j( A' H( X3 O
    在值类型中实现相等运算符 (==)6 T2 j0 A5 x$ k( Y. o
    大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。
    " N, b" u% }1 f: e, Z* g$ o应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。
    : N  ^- E  P6 y! D每次重写 Equals 方法时都实现相等运算符 (==)。! X/ N+ s" R8 Y( Q& D
    在引用类型中实现相等运算符 (==)# [& T1 T2 G. D, E2 t5 R* j
    大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。* B/ [. N6 z% E; a8 H
    如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。$ D6 D/ d0 }, W; u8 b! ^6 b2 m0 n
    好了,下面是考题,相信答案大家都知道了。
    - \6 [8 Z$ `$ o+ |3 n  G            Console.WriteLine((2 + 2) == 4);# v4 M) p) G& C8 r" Z0 O
                object s = 1;
    ) d. ]% e! M  f  ~0 ~8 B            object t = 1;% Z  J4 S$ f3 c1 \
                Console.WriteLine(s == t);$ W) a( p& i+ @
                string a = "hello";
    $ s% Y# |5 o$ g* R            string b = String.Copy(a);
    2 H% P( f! Z) S* Y% m) W            string c = "hello";: a0 `& q5 `+ }8 x) P% X  W/ g
                Console.WriteLine(a == b);
    9 b. C/ I! e+ G4 U# ?5 n            Console.WriteLine((object)a == (object)b);) g4 Z! g* Z. n4 X- x' ^
                Console.WriteLine((object)a == (object)c);( m! ^" M, q* Q/ S7 p; `' r
    答案:TRUE, FALSE, TRUE, FALSE, TRUE
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-10-31 02:36

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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