【C#】 參考類型 , 值類型 Equals方法 和 ==

  • 7576
  • 0
  • c#
  • 2018-02-27

為什麼 p1 不等於 p2  但 i1 = i2

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
}

Person p1 = new Person();
Person p2 = new Person();
int i1 = 0;
int i2 = 0;
Console.WriteLine(p1==p2); //這是false
Console.WriteLine(i1==i2); //這是true

因為 值類型 和 參考類型的 Equals比較方式不一樣....

  • == 是運算元 
  • Equals是方法這個方法定義在Object類別上

值類型的等於 是比較變數內容

例如100 == 100 是True 因為100 = 100 (這不是廢話XD)

static void Main(string[] args)
{
    int num1 = 100;
    int num2 = 100;
    Console.WriteLine(num1.Equals(num2));

    Console.ReadKey();
}

 

但如果是前面敘述 Person物件比較 

雖然看起來會等於 但因為 p1物件位置 != p2物件位置  所以是不正確的

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
}

static void Main(string[] args)
{
    Person p1 = new Person();
    Person p2 = new Person();
    Console.WriteLine(p1 == p2);
    Console.ReadKey();
}

那如果我要Person比較裡面屬性的內容怎麼辦?

有幾種辦法可以達成

  1. 重寫Equals方法 
  2. 實現 IEqualityComparer<T> 介面 (推薦這種)
  3. 重新定義 operator == (比較特別的方法)

1. 重寫Equals方法  override Equals方法 直接比較值


public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        Person p1 = obj as Person;
        if (p1 == null)
        {
            return false;
        } 
        return p1.Age == this.Age && p1.Name == this.Name;
    }
}

 

2.實現 IEqualityComparer<T> 介面

呼叫介面的比較方法(這個介面可搭配某些Linq方法)

public class PersonCompare : IEqualityComparer<Person>
{
    public bool Equals(Person a, Person b)
    {
        return a.Age == b.Age && a.Name == b.Name;
    }

    public int GetHashCode(Person obj)
    {
        return obj.GetHashCode();
    }
}

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
}

static void Main(string[] args)
{
    PersonCompare pCompare = new PersonCompare();

    Person p1 = new Person();
    Person p2 = new Person();
    Console.WriteLine($"Normal {p1.Equals(p2)}"); //Normal Compare
    Console.WriteLine($"pCompare {pCompare.Equals(p1, p2)}"); //Used IEqualityComparer Interface
    Console.ReadKey();
}

 

3.重新定義 operator == (這是我覺得最有趣的方法)

重新定義==運算子,因為原本是比較位置 可以改成你想要的方式

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }

    public static bool operator ==(Person a, Person b)
    {
        return a.Age == b.Age && a.Name == b.Name;
    }

    public static bool operator !=(Person a, Person b)
    {
        return a.Age != b.Age || a.Name != b.Name;
    }
}

static void Main(string[] args)
{

    Person p1 = new Person();
    Person p2 = new Person();
    Console.WriteLine(p1.Equals(p2)); 


    Console.ReadKey();
}

 

小結:

注意 值類型 和 參考類型的 Equals比較方式不一樣  
如果要比較參考類型內容是否一樣 需要做些手腳

如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^