.NET-5-判断两个对象是否为同一个对象

我们在比较两个对象的时候

如果两个对象是值类型,则直接比较的就是这两个对象在栈空间所存储的内容是否相同

如果两个对象是引用类型,比如两个自定义的类对象,他们比较的是两个对象在堆中的地址是否相同

但是string类型的比较特别,虽然string是引用类型,但是他们在比较的时候应为对其做了特殊处理,所以比较方式有点不同


值类型的不做讨论,这里比较两个引用类型的对象

一般比较两个对象是否相同使用三种方式==,Equals,object.ReferenceEquals

object.ReferenceEquals比较的才是真正的两个对象的地址

==和Equals如果被重写的话,则比较的可能不是两个对象的地址

例如string就对==运算符和Equals做了特殊处理,这里比较的就不一定是两个对象的地址

代码实例如下:

public class Class4

    {
        /*判断两个对象是否为同一个对象
         * 指向堆里面的同一个内存空间,就是同一个对象
         * 在这里只判断引用类型的是否为同一个对象
         * 对值类型不做判断,对值类型判断是否为同一个对象没有意义
         *
         * 使用object.ReferenceEquals,可以始终准确验证两个对象是否为同一个对象
         * 使用==和Equals不能保证判断的都是正确的
         * 应为string有对着两个方法进行了重载或者重写导致的判断规则不同
         */


        public static void Test1()
        {
            Console.WriteLine("自定义类:");
            Person1 p = new Person1();
            p.Name = "丽丽";
            p.Age = 18;

            Person1 p1 = new Person1();
            p1.Name = "丽丽";
            p1.Age = 18;

            Console.WriteLine(p == p1);//false
            Console.WriteLine(p.Equals(p1));//false
            Console.WriteLine(object.ReferenceEquals(p, p1));//false


            p = p1;
            Console.WriteLine(p == p1);//true
            Console.WriteLine(p.Equals(p1));//true
            Console.WriteLine(object.ReferenceEquals(p, p1));//true


            Console.WriteLine("string类型:");
            /*string类型在使用如下的方式声明一个变量的时候
             * 会在堆中查找有没有相同的对象"asd"
             * 如果有,会把找到的对象的地址赋值给这个变量
             * 如果没有才会创建一个新的对象,开辟一个新的空间
             */
            string s1 = "asd";
            string s2 = "asd";
            Console.WriteLine(s1 == s2);//true
            Console.WriteLine(s1.Equals(s2));//true
            Console.WriteLine(object.ReferenceEquals(s1, s2));//true


            Console.WriteLine("数组类型:");
            /*在new string的时候,会在堆中创建一个新的空间
             * 所以cs1和cs2堆的地址是不同的,他们不是同一个对象
             */
            string cs1 = new string(new char[] { 'a', 'b', 'c' });
            string cs2 = new string(new char[] { 'a', 'b', 'c' });
            /*这里string会对运算符进行重载
             * 之后会调用Equals方法进行判断
             * 所以这里运算的结果和Equals的运算记过相同
             */
            Console.WriteLine(cs1 == cs2);//true
            /* string类中有两个Equals方法
             * 一个是继承自object类并且重写的方法,他的入参是object类型
             * 一个是string类自己重载的方法, 他的入参是string类型
             * 这领个方法都是调用object.ReferenceEquals判断两个对象是否为同一个对象,如果是返回true
             * 如果不是,则继续判断两个字符串的每个字符是否相同,如果相同返回true,不相同返回false
             * 所以这里虽然两个对象不是同一个对象,但是仍然返回true
             */
            Console.WriteLine(cs1.Equals(cs2));//true
            Console.WriteLine(object.ReferenceEquals(cs1, cs2));//false

        }
    }



    public class Person1
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private int _age;

        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }


        ///// <summary>
        ///// 对Equals进行重写
        ///// </summary>
        ///// <param name="obj"></param>
        ///// <returns></returns>
        //public override bool Equals(object obj)
        //{
        //    Person1 p = obj as Person1;
        //    if (p == null)
        //    {
        //        return false;
        //    }
        //    else
        //    {
        //        if (this.Name == p.Name && this.Age == p.Age)
        //        {
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //}

        ///// <summary>
        ///// 对操作符进行重载
        ///// 这里写的有问题,应为下面有调用==操作符的地方,会出现递归调用。。。
        ///// </summary>
        ///// <param name="p1"></param>
        ///// <param name="p2"></param>
        ///// <returns></returns>
        //public static bool operator ==(Person1 p1, Person1 p2)
        //{
        //    return Equals(p1, p2);
        //}

        //public static bool operator !=(Person1 p1, Person1 p2)
        //{
        //    return !Equals(p1, p2);
        //}


        //private static bool Equals(Person1 p1, Person1 p2)
        //{
        //    if (p1 == null || p2 == null)
        //    {
        //        return false;
        //    }
        //    if (p1.Age == p2.Age && p1.Name == p2.Name)
        //    {
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}
    }




string中参数为string类型的Equals方法


string中对运算符==的重载