详解Equals()静态方法、虚方法,与等号的区别

 object st1 = 1;
            object st2 = 1;
            Console.WriteLine(Equals(st1, st2));
            Console.WriteLine(st1.Equals(st2));
            Console.WriteLine(st1 == st2);
            Console.WriteLine("------------------------------------");
            object st3 = 1;
            object st4 = 1;
            Console.WriteLine(Equals(st3, st4));
            Console.WriteLine(st3.Equals(st4));
            Console.WriteLine(st3 == st4);
            Console.WriteLine("------------------------------------");
            object st5 = null;
            object st6 = 1;
            Console.WriteLine(Equals(st5, st6));
           // Console.WriteLine(st5.Equals(st6));//这一句会报异常,注释掉
            Console.WriteLine(st5 == st6);
            Console.WriteLine("------------------------------------");
            object st7 = 1;
            object st8 = st7;
            Console.WriteLine(Equals(st7, st8));
            // Console.WriteLine(st7.Equals(st8));//这一句会报异常,注释掉
            Console.WriteLine(st7 == st8);

运行结果:

True
True
False
------------------------------------
True
True
False
------------------------------------
False
False
------------------------------------
True
True
请按任意键继续. . .


这一段结果说明:等号比较的是两个的引用,即他们引用的是否是同一对象。

Equals()的静态方法和虚方法都比较的是值,只需要判断值是否相同就行了。但是Equals静态方法可以传值NULL,如果是虚方法就会报异常。静态方法执行的之后只是将null报错的状态去掉了,最后还是执行的虚方法,所以如果重写虚方法,静态方法的结果也会跟随改变,下面会验证

注意一点:string类型是特殊的引用类型一般都是将其当作值类型使用,string不管是等号比较还是Equals比较都是比较值,string比较的时候等号比较会被重写,实际上是用Equasl比较的。(这里不做验证,在此博客已有大佬做过了验证https://www.cnblogs.com/chen0720/p/3209398.html

有一种引用类型的比较需要重写Equasl方法:

  pe p1 = new pe();
            p1.name = "1";
            pe p2 = new pe();
            p2.name = "1";
            Console.WriteLine(p1.Equals(p2));
 Console.WriteLine(Equals(p1,p2));

若Pe类中没有重写Equals方法,则返回值为false,fanlse,

False
False
请按任意键继续. . .

为什么呢,不是说引用类型Equasl比较的是值吗,与地址无关怎么会是false,

这是因为父类的Equals不知道pe类有哪些字段,无法将他们进行比较。这时就需要在pe类里面重写Equasl方法了

class Pe
        {
            public string name { get; set; }
            public override bool Equals(object o)
            {
                pe p = o as pe;
                if (this.name == p.name && this.name == p.name)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

现在Equasl方法返回的结果就是true,true了

扫描二维码关注公众号,回复: 3281150 查看本文章

True
True
请按任意键继续. . .
(也验证了上面所说:静态方法实际上执行的是虚方法)

上面所说都是引用类型的,值类型的比较一般使用Equasl比较,因为值类型一般只需要比较值。如果一个值类型的结构等号比较的话会报错。说到值类型比较这里说一下ReferenceEquals()方法,此方法跟等号比较一样,都是比较引用。如果把这个方法拿来比较值类型不管值想不想等都会返回false。值类型在使用ReferenceEquals()和Equasl()方法比较的时候,值类型会被装箱,也就是转换成引用类型,这时候比较的两个值类型的内存地址就不会一样,如果使用ReferenceEquals就会一直返回false。所以说值类型一般使用Equals方法比较。必要时重写Equals方法。

猜你喜欢

转载自blog.csdn.net/weixin_40068689/article/details/81978353