相等性比较 (== ,Equals,ReferenceEquals)

Posted jizhiqiliao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了相等性比较 (== ,Equals,ReferenceEquals)相关的知识,希望对你有一定的参考价值。

1.前言

在C#中存在三种比较对象相等性的方法,== ,Equals,以及 ReferenceEquals,对于这三种不同形式的相等性比较,他们又存在着那些差异呢?

2.比较形式

在C#中存在着两种比较形式,即引用相等的比较和值相等的比较。对于值类型和引用类型,两者在进行比较时的内容也是不同的。

  • 值类型的比较:比较两个值类型所包含的数值是否相等
  • 引用类型的比较:引用类型的比较分为两部分,一个是引用类型的引用是否一致(存放在堆栈中),另一个是引用类型的数值是否一致(存放在托管堆)。因此,对于引用类型存在两种形式的比较

在默认情况下,对值类型进行数值比较,对引用类型进行引用比较。

3.三种比较的详细分析

3.1 ==(相等运算符)

有关 == 的使用主要可以分为三种情况:

  1. 对值类型:如果其操作数的值相等,则相等运算符 (==) 返回 true,否则返回 False。 
  2. 对 string 外的引用类型,如果两个操作数引用同一对象,则==会返回 true。 
  3. 对 string 类型,==会比较字符串的值。这是由于 string 是微软封装的一个字符串类,在内部他已经对 == 操作符进行了重写,重写后比较的则是两个变量的内容是否相同。
class Test
{ }
class Program
{
    static void Main(string[] args)
    {
        int a = 1;
        int b = 1;
        Test A = new Test();
        Test B = A;
        string c = "qwer";
        string d = "qwer";
        Console.WriteLine(a == b);
        Console.WriteLine(A == B);
        Console.WriteLine(c == d);
        Console.WriteLine((2 + 2) == 4);
        Console.ReadKey();
    }
}

输出结果如下:

True
True
True
True

3.2 Equals

有关 Equals 的使用主要可以分为三种情况:

  1. 对值类型:作用与 == 运算符相同,对两者的数值进行比较
  2. 对 string 外的引用类型,Equals 比较的永远是变量的内容是否相同但必须对 Object 中的 Equals 实现重写。 
  3. 对 string 类型:作用与 == 运算符相同,对字符串的值进行比较
class Test
{
    string name;
    public Test(string name)
    {
        this.name = name;
    }
}
class Program
{
    static void Main(string[] args)
    {
        int a = 1;
        int b = 1;
        Test A = new Test("kyle");
        Test B = new Test("kyle");
        string c = "qwer";
        string d = "qwer";
        Console.WriteLine(a.Equals(b));
        Console.WriteLine(A.Equals(B));
        Console.WriteLine(c.Equals(d));
        Console.WriteLine((2+2).Equals(4));
        Console.ReadKey();
    }
}

输出结果如下:

True
False
True
True

Equals 始终实现的是对值的比较,明显对象 A,B 的值是相等的,但 A.Equals(B) 的输出结果确实 False,这是因为 Equals 是 Object 中的一个虚方法,而 Test 类中没有对其进行重写,因此此时调用的仍是父类中的 Equals 方法。但是父类是无法知道 Test 的成员字段,因此返回的是 false。因此想要比较两个变量的内容是否相同,那就应该重写 Equals 方法。

public override bool Equals(object obj)
{
    Person t = obj as Person;
    if(this.name == t.name)
    {
        return true;
    }
    else
    {
        return false;
    }
}

3.3 ReferenceEquals

ReferenceEquals 是 Object 中的静态方法,对于值类型或者引用类型都是用来检查引用是否相同

  1. 由于检查引用是否相同,所以对值类型始终返回 False
  2. 对于引用类型,当可两者引用相同时返回 True
class Person
{
    string name;
    public Person(string name)
    {
        this.name = name;
    }

    class Program
    {
        static void Main(string[] args)
        {
            int a = 1;
            int b = 1;
            Person A = new Person("kyle");
            Person B = new Person("kyle");
            Person C = B;
            Console.WriteLine(ReferenceEquals(a, b));
            Console.WriteLine(ReferenceEquals(A, B));
            Console.WriteLine(ReferenceEquals(B, C));
            Console.ReadKey();
        }
    }
}

 

输出结果如下:

False
False
True

 

以上是关于相等性比较 (== ,Equals,ReferenceEquals)的主要内容,如果未能解决你的问题,请参考以下文章

C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?

转载C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?

转载C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?

JSF 验证器与字符串的相等性比较

C#相等性 - 为值类型重定义相等性

Object Equals && GetHashCode