C# List Contains()用於引用類型的使用

導讀

C#中變量可分爲值類型和引用類型,值類型儲存在棧中,引用類型儲存在堆中,棧中儲存在堆中的引用地址,List泛型的Contais在比較值類型時,直接比較值,但是在比較引用類型時,比較的是引用地址。

  • 問題引入

實際開發中,我們經常會把同類型的一系列對象封裝到List集合中,當我們有需要在封裝對象到List集合中時,排除重複的對象,這時直接使用

if(!List.Contains(obj))
{
    List.Add(bj);
}

List.Contains(obj)返回false時 ,我們給集合中添加,這種邏輯是沒有問題的,List.Contains(obj)比較的是:原來List集合中的對象的儲存地址和當前需要添加對象obj在堆中儲存的地址 ,所以即便有兩個對象相等,但是它們儲存的地址不同,所以List.Contains仍然返回false

  • 解決方案
    List.Contains(obj)調用的是obj對象對應的類的Equals()方法,我們可以按需要重寫這個方法和GetHashCode()方法,即可按自己的需求來定義Contains()比較方式。

  • 案例

public class Person
{
   private string Number;
   private string personName;

   public Person(string name, string Number)
   {
      this.personName = name;
      this.Number= Number;
   }

   public bool Equals(Person p)
   {
       //按需求定製自己需要的比較方式
      return (this.personName == p.personName && this.Number == p.Number);
   }

   public override int GetHashCode()
   {
      return this.Number.GetHashCode(); 
   }
}

public class Example
{
   public static void Main()
   {
      Person p1 = new Person("John", "63412895");
      Person p2 = new Person("Jack", "63412895");
      List<Person> List = new List<Person>();
      List.Add(p1);
      List.Add(p2);
      Person p3 = new Person("John", "63412895");
      if(!List.Contains(p3))//沒有重寫前函數返回false,現在返回true
      {
          List.Add(p3);
      }
   }
}

MSDN關於Equels重寫的介紹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章