C# 关于Equals,==,ReferenceEquals一些比较

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            /*Equals 的默认实现支持引用相等性(对于引用类型)和按位相等性(对于值类型)。 
             值相等性是指所比较的对象具有相同的值,但是具有不同的二进制表示形式。
             例如,请考虑两个分别表示数字 1.10 和 1.1000 的 Decimal 对象。 Decimal 对象不具有按位相等性,
             * 因为它们具有不同的二进制表示形式,因此会考虑不同数量的尾随零。 但是,这些对象具有值相等性,
             * 因为在进行比较时尾随零无关紧要,数字 1.10 和 1.1000 被视为相等。
*/
            string s1 = "Jon";
            string s2 = "Jon";
            Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
       s1, s2, Object.Equals(s1, s2));

            string s3 = null;
            string s4 = "Jon";
            Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
       s1, s2, Object.Equals(s3, s4));

            string s5 = null;
            string s6 = null;
            Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
       s1, s2, Object.Equals(s5, s6));

            decimal d1 = 1.10m;
            decimal d2 = 1.1000m;
            Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
      s1, s2, Object.Equals(d1, d2));
            person per = new person();
            student stua = new student(2, 2, 222);
            student stub = new student(2, 2, 222);
            Console.WriteLine(per.Equals(stua));
            Console.WriteLine(stub.Equals(stua));
            Console.WriteLine(stua == stub);
            object a = new object();
            object b = a;
            Console.WriteLine(System.Object.ReferenceEquals(a, b));

        }

    }
    public class person : Object
    {
        public int x, y;
        public person(int _x, int _y)
        {
            this.x = _x;
            this.y = _y;
        }
        public person()
        {
            this.x = 1;
            this.y = 1;
        }
        /*若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,请使用 Equals。 
         下面是针对实现值类型的准则:
         考虑重写 Equals,以便在 ValueType 上获得比 Equals 的默认实现所提供的性能增强的性能。 
         如果重写 Equals 并且语言支持运算符重载,则必须重载值类型的相等运算符。 
         下面是针对实现引用类型的准则:
         如果引用类型的语义是基于该类型表示某个(些)值的事实,则考虑对该类型重写 Equals。 
         即使大多数引用类型重写 Equals,它们也必须不能重载相等运算符。
         * 但是,如果实现的引用类型想要具有值语义(如复杂的数字类型),则必须重写相等运算符。
         */
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType()) return false;
            person p = (person)obj;
            return (p.x == x) && (p.y == y);
        }
        public override int GetHashCode()
        {
            return x ^ y;
        }
    }

    public class student : person
    {
        private int z;
        public student(int _x, int _y, int _z)
        {
            this.x = _x;
            this.y = _y;
            this.z = _z;
        }
        public override bool Equals(object obj)
        {
            return base.Equals(obj) && (((student)obj).z == z);
        }
        public override int GetHashCode()
        {
            return base.GetHashCode() ^ z;
        }
        /*
         默认情况下,运算符 == 通过判断两个引用是否指示同一对象来测试引用是否相等。
         * 因此引用类型不需要实现运算符 == 就能获得此功能。当类型不可变(即实例中包含的数据不可更改)时,
         * 通过重载运算符 == 来比较值是否相等而不是比较引用是否相等可能会很有用,因为作为不可变的对象,只要其值相同,
         * 就可以将其视为相同。建议不要在非不可变类型中重写运算符 ==。 
         */
        public static bool operator ==(student a, student b)
        {
            if (System.Object.ReferenceEquals(a, b))
            {
                return true;
            }
            if ((object)a == null || (object)b == null)
            {
                return false;
            }
            return (a.x == b.x) && (a.y == b.y) && (a.z == b.z);

        }
        public static bool operator !=(student a, student b)
        {
            return !(a == b);
        }

    }

}
image
posted @ 2011-03-17 22:55  Jon.Zhiwei@hotmail.com  Views(367)  Comments(0)    收藏  举报