zoukankan      html  css  js  c++  java
  • c#中 ==与equals有什么区别


    对于值类型引用类型来说比较过程怎样的?

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace ConsoleApplication1
    {
        class Person
        {
            private string name;
    搜索
            public string Name
            {
                get { return name; }
                set { name = value; }
            }

    public Person(string name)
            {
                this.name = name;
            }
        }

    class Program
        {
            static void Main(string[] args)
            {
                string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
                string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
                Console.WriteLine(a == b);
                Console.WriteLine(a.Equals(b));

                object g = a;
                object h = b;
                Console.WriteLine(g == h);
                Console.WriteLine(g.Equals(h));

                Person p1 = new Person("jia");
                Person p2 = new Person("jia");
                Console.WriteLine(p1 == p2);
                Console.WriteLine(p1.Equals(p2));

    Person p3 = new Person("jia");
                Person p4 = p3;
                Console.WriteLine(p3 == p4);
                Console.WriteLine(p3.Equals(p4));

                Console.ReadLine();
            }
        }
    }

    答案为何为true true false true  false false true true

    因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
      "==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
      "equals" : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
        而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。
        因此在上面的例子中,第一对输出 ,字符串a和字符串b的两个比较是相等的。
        对于 第二对输出 object g = a 和object h = b ,  在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:
            string a="aa";
            string b="aa";
    则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
    对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
    对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。

    MSDN中就有介绍啊:
    下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:

    每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。

    每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。

    每次实现 IComparable 时都要重写 Equals 方法。

    实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载

    不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。

    有关 Equals 方法的相关信息,请参见实现 Equals 方法。

    在值类型中实现相等运算符 (==)
    大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。

    应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。

    每次重写 Equals 方法时都实现相等运算符 (==)。

    在引用类型中实现相等运算符 (==)
    大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。

    如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。

    好了,下面是考题,相信答案大家都知道了。

                Console.WriteLine((2 + 2) == 4);
                object s = 1;
                object t = 1;
                Console.WriteLine(s == t);

                string a = "hello";
                string b = String.Copy(a);
                string c = "hello";

                Console.WriteLine(a == b);
                Console.WriteLine((object)a == (object)b);
                Console.WriteLine((object)a == (object)c);

    答案:TRUE, FALSE, TRUE, FALSE, TRUE

    操作符“==”在值类型情况下表示是否值相等.
    equals 判断是否是同一个对象的引用.
    string的==和equals都是比较值。

  • 相关阅读:
    ural(Timus) 1019 Line Painting
    ACMICPC Live Archive 2031 Dance Dance Revolution
    poj 3321 Apple Tree
    其他OJ 树型DP 选课
    poj 3548 Restoring the digits
    ACMICPC Live Archive 3031 Cable TV Network
    递归循环获取指定节点下面的所有子节点
    手动触发asp.net页面验证控件事件
    子级Repeater获取父级Repeater绑定项的值
    没有列名的数据绑定
  • 原文地址:https://www.cnblogs.com/itjeff/p/3368257.html
Copyright © 2011-2022 走看看