C#中Equals和GetHashCode使用及區(qū)別
Equals和GetHashCode
Equals每個實現(xiàn)都必須遵循以下約定:
- 自反性(Reflexive): x.equals(x)必須返回true.
- 對稱性(Symmetric): x.equals(y)為true時,y.equals(x)也為true.
- 傳遞性(Transitive): 對于任何非null的應(yīng)用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)必須返回true.
- 一致性(Consistence): 如果多次將對象與另一個對象比較,結(jié)果始終相同.只要未修改x和y的應(yīng)用對象,x.equals(y)連續(xù)調(diào)用x.equals(y)返回相同的值l.
- 非null(Non-null): 如果x不是null,y為null,則x.equals(y)必須為false
GetHashCode:
- 兩個相等對象根據(jù)equals方法比較時相等,那么這兩個對象中任意一個對象的hashcode方法都必須產(chǎn)生同樣的整數(shù)。
- 在我們未對對象進行修改時,多次調(diào)用hashcode使用返回同一個整數(shù).在同一個應(yīng)用程序中多次執(zhí)行,每次執(zhí)行返回的整數(shù)可以不一致.
- 如果兩個對象根據(jù)equals方法比較不相等時,那么調(diào)用這兩個對象中任意一個對象的hashcode方法,不一同的整數(shù)。但不同的對象,產(chǎn)生不同整數(shù),有可能提高散列表的性能.
IEqualityComparer實現(xiàn)
下面我們創(chuàng)建一個學(xué)生類,從而進一步的實現(xiàn)我們對象數(shù)據(jù)的對比
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
通過如下代碼我們將通過distinct方法實現(xiàn)我們的過濾.
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>
{
new Student{ Name = "MR.A", Age = 32},
new Student{ Name = "MR.B", Age = 34},
new Student{ Name = "MR.A", Age = 32}
};
Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count());//distinctStudents has Count = 3
Console.ReadLine();
}
}
我們需要達到的是忽略相同數(shù)據(jù)的對象,但是并沒有達到我們?nèi)缙诘男Ч?因為是distinct默認比較的是對象的引用...所以這樣達不到我們預(yù)期效果.那我們修改一下來實現(xiàn)我們預(yù)期效果.
在默認情況下Equals具有以下行為:
- 如果實例是引用類型,則只有引用相同時, Equals才會返回true。
- 如果實例是值類型,則僅當(dāng)類型和值相同時, Equals才會返回true。
Distinct(IEnumerable, IEqualityComparer)
通過使用指定的 IEqualityComparer 對值進行比較,返回序列中的非重復(fù)元素.
類型參數(shù)
- TSource source 的元素類型。
參數(shù)
- source IEnumerable 要從中移除重復(fù)元素的序列。
- comparer IEqualityComparer 用于比較值的 IEqualityComparer。
返回
- IEnumerable
一個包含源序列中的非重復(fù)元素的 IEnumerable。
我們來看如下代碼片段
public class StudentComparator : EqualityComparer<Student>
{
public override bool Equals(Student x,Student y)
{
return x.Name == y.Name && x.Age == y.Age;
}
public override int GetHashCode(Student obj)
{
return obj.Name.GetHashCode() * obj.Age;
}
}
上述代碼片段如果兩個Equals返回的true并且GetHashCode返回相同的哈希碼,則認為兩個對象相等.
重寫Equals和GetHashCode
var stu1 = new Student { Name = "MR.A", Age = 32 };
var stu2 = new Student { Name = "MR.A", Age = 32 };
bool result = stu1.Equals(stu2); //false because it's reference Equals
上述代碼片段執(zhí)行后結(jié)果非預(yù)期效果.我們將進一步的去實現(xiàn)代碼,以達到預(yù)期效果....
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public override bool Equals(object obj)
{
var stu = obj as Student;
if (stu == null) return false;
return Name == stu.Name && Age == stu.Age;
}
public override int GetHashCode()
{
return Name.GetHashCode() * Age;
}
}
var stu1 = new Student { Name = "MR.A", Age = 32 };
var stu2 = new Student { Name = "MR.A", Age = 32 };
bool result = stu1.Equals(stu2); //result is true
我們再使用LINQ Distinct方法進行過濾和查詢,同時將會檢查Equals和GetHashCode
List<Student> students = new List<Student>
{
new Student{ Name = "MR.A", Age = 32},
new Student{ Name = "MR.B", Age = 34},
new Student{ Name = "MR.A", Age = 32}
};
Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count()); //distinctStudents has Count = 2
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
作者:@馮輝
出處:https://www.cnblogs.com/yyfh/p/12245916.html?utm_source=tuicool&utm_medium=referral
相關(guān)文章
C#中winform窗體實現(xiàn)注冊/登錄功能實例(DBHelper類)
在編寫項目時,編寫了一部分關(guān)于登錄頁面的一些代碼,下面這篇文章主要給大家介紹了關(guān)于C#中winform窗體實現(xiàn)注冊/登錄功能(DBHelper類)的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-06-06
C#使用SQL DataReader訪問數(shù)據(jù)的優(yōu)點和實例
今天小編就為大家分享一篇關(guān)于C#使用SQL DataReader訪問數(shù)據(jù)的優(yōu)點和實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10
C#使用Socket實現(xiàn)服務(wù)器與多個客戶端通信(簡單的聊天系統(tǒng))
這篇文章主要介紹了C#使用Socket實現(xiàn)服務(wù)器與多個客戶端通信(簡單的聊天系統(tǒng)),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02

