比较对象相等性的四种方法

比较对象相等性的四种方法

        System.Object定义了3个不同的方法,来比较对象的相等性:ReferenceEquals()和两个版本的Equals()。再加上比较运算符(==),实际上是有四种比较相等的方式。

    在编程中实际上我们只需要这两种比较,c#中类型也就这两种

  (1)值类型的比较:一般我们就是判断两个值类型实例的各自包含的值是否相等

  (2)引用类型的比较:由于引用类型在内存中的分布有两部分,一个是引用类型的引用(存在于线程栈中),一个是引用类型的值(存在于托管堆);所以我们比较引用类型也就存在两种比较

    默认情况下:值类型比较的是两个值是否相等(不装箱情况下),引用类型比较的是两个引用是否相等。

1.ReferenceEquals()

        ReferenceEquals()是一个静态方法,测试两个引用是否引用类的同一个实例。特别是两个引用是否包含内存中的相同地址。作为静态方法,他不能重写,所以system.Object的实现代码保持不变。

2.虚方法Equals()

        Equals()虚拟版本的System.Object实现代码也可以用于比较引用。但因为这个方法是虚方法,所以可以在自己的类中重写他,从而按值来比较对象。

        注意:对于Object对象比较的是引用!然而对于值类型,类型相同(不会进行类型自动转换),并且数值相同(对于struct的每个成员都必须相同),则Equals返回 true,否则返回false。这是为什么呢? 这是因为内置的值类型都重写了Object.Equals方法,所以值类型的Equals方法与引用类型的Equals就产生了不同的效果。

      Equals在程序运行时决定比较的类型--根据对象的实际类型进行比较,根据对象的类型调用他们各自的Equals虚方法。

3.静态的Equals()方法

        Equals()的静态版本与虚拟实例版本的作用相同,其区别是静态版本带有两个参数,并对他们进行相等性的比较。

        用反编译工具反编译System.dll得到方法的实现源码:

  public static bool Equals(object objA, object objB)
    {
          if (objA == objB)
         { return true; }
         if ((objA != null) && (objB != null))
         { return objA.Equals(objB); }
        return false;
     }

 

4.比较运算符(==)

        定义:静态相等符号,对应存在的!=,这个符号是一个可以重载的二元操作符,可以用于比较两个对象是否相等。使用==比较对象时,C#在编译时就决定了所比较的类型,而且不会执行任何虚方法(Object.Equals)。这是大家所期望的相等行比较。

  • 对于内置值类型,==判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false
  • 对于引用类型,则==一般情况下比较的这是引用类型的引用是否相等。

  注意:但是某些内置的引用类型重载了==符号,例如string就重载==,使其比较的不是两个字符串的引用,而是比较的两个字符串字面量是否相等,所以对于引用类型最好不要使用==符号进行相等性比较,避免混淆。

    【对于引用类型利用==除了string是比较其值外,其余都是比较其引用,因为string是经常需要操作,所以会直接比较其值,所以会对其特殊对待,所以如果遇见特殊的引用类型需要查看一下是否进行了==重载,默认情况大家都可以把==在比较引用类型时当成比较引用!

下面是关于四种比较的例子:

 class Program
    {
        static void Main(string[] args)
        {
            string personName1 = "张三";
            string personName2 = "李四";

            int age1 = 22;
            int age2 = 22;

            Student Person1, Person2;
            Person1 = new Student(personName1);
            Person2 = new Student(personName2);

            //1.实例Equals() 虚方法,比较引用,可重写来比较值
            bool b1 = personName1.Equals(personName2);
            bool b2 = age1.Equals(age2);
            bool b3 = Person1.Equals(Person2);
            Console.WriteLine("1.实例Equals()结果:");
            Console.WriteLine("personName1.Equals(personName2) :{0}", b1);
            Console.WriteLine("age1.Equals(age2) :{0}", b2);
            Console.WriteLine("Person1.Equals(Person2) :{0}", b3);

            Console.WriteLine("------------------------------------------------");

            //2.==
            bool b4 = personName1 == personName2;
            bool b5 = age1 == age2;
            bool b6 = Person1 == Person2;

            Console.WriteLine("2.==:");
            Console.WriteLine("personName1 == personName2 :{0}", b4);
            Console.WriteLine("age1 == age2 :{0}", b5);
            Console.WriteLine("Person1 == Person2 :{0}", b6);

            Console.WriteLine("------------------------------------------------");

            //3.ReferenceEquals()
            bool b7 = ReferenceEquals(personName1, personName2);
            bool b8 = ReferenceEquals(age1, age2);
            bool b9 = ReferenceEquals(Person1, Person2);

            Console.WriteLine("3.ReferenceEquals():");
            Console.WriteLine("ReferenceEquals(personName1,personName2) :{0}", b7);
            Console.WriteLine("ReferenceEquals(age1,age2) :{0}", b8);
            Console.WriteLine("ReferenceEquals(Person1,Person2) :{0}", b9);

            Console.WriteLine("------------------------------------------------");

            //4.静态的Equals()
            bool b10 = Equals(personName1, personName2);
            bool b11 = Equals(age1, age2);
            bool b12 = Equals(Person1, Person2);

            Console.WriteLine("3.Equals():");
            Console.WriteLine("Equals(personName1,personName2) :{0}", b10);
            Console.WriteLine("Equals(age1,age2) :{0}", b11);
            Console.WriteLine("Equals(Person1,Person2) :{0}", b12);


            Console.WriteLine("------------------------------------------------");
            int i = 5;
            float j = 5;
            bool bb = i.Equals(j);//不会进行类型转换
            bool bb1 = i == j;
            bool bb2 = Equals(i, j);
            Console.WriteLine("i.Equals(j):{0}", bb);
            Console.WriteLine("i==j:{0}", bb1);
            Console.WriteLine("Equals(i,j):{0}", bb2);
            Console.WriteLine();
            Console.ReadKey();
        }

    }
    public class Student
    {
        private string name;
        public Student(string name)
        {
            this.name = name;
        }
        public void ShowName()
        {
            Console.WriteLine(this.name);
        }
    }

运行结果如下:

猜你喜欢

转载自blog.csdn.net/weixin_39504659/article/details/85000043