LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C# 7個方法比較兩個對象是否相等

admin
2024年12月12日 10:40 本文熱度 341

前言

在現(xiàn)實(shí)中的編程生活里,我們時常遇到一個棘手的問題:如何比較兩個相同類型的對象是否 "相等",比如在 ERP 系統(tǒng)中,企業(yè)的信息非常重要,每一次更新維護(hù),都需要系統(tǒng)自動地詳細(xì)記錄更新前后企業(yè)不一致的信息、更新時間和更新人等等。

但是,直接比較通常只能告訴我們它們是否指向同一個內(nèi)存地址,而不能告訴我們它們的內(nèi)容是否一致,所以即使兩個相同類型的對象的值都一致,程序還是偏偏說:"對不起,他們沒關(guān)系!" 那我們應(yīng)該怎么辦呢?別急,接下來我們一起探索。

在 C# 中,要比較兩個對象實(shí)例是否相等,有一些常用的方法。

比如實(shí)現(xiàn) IEquatable<T> 接口、重寫 Object.Equals 方法,或使用自定義比較邏輯等等。

以下是 7 種常用的方法:

1. 實(shí)現(xiàn) IEquatable接口

實(shí)現(xiàn) IEquatable<T> 接口是一個好習(xí)慣,就像在你的小屋里掛上一個 "歡迎光臨" 的牌子,讓外界知道你準(zhǔn)備好接受比較了,實(shí)現(xiàn)這個接口之后,你還可以創(chuàng)建更強(qiáng)類型的比較方法。

public class Test : IEquatable<Test>
{
    public int Id { getset; }
    public string Name { getset; }

    public bool Equals(Test other)
    {
        if (other == null)
            return false;

        return this.Id == other.Id && this.Name == other.Name;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Test);
    }

    public override int GetHashCode()
    {
        return (Id, Name).GetHashCode(); // 可以使用 C# 7.3 中的元組
    }
}

2. 重寫 Object.Equals 和 GetHashCode 方法

這是老派的做法,但依然有效。

當(dāng)你重寫了 Equals 和 GetHashCode 方法后,你就能告訴對象們: "嘿,你們倆是一樣的!" 。

如果你使用的是 .NET8 或更高版本時,你還可以使用 源生成器 (source generators) 特性幫助自動生成 EqualsGetHashCode 等常用方法,編程工作更輕松!

public class Test
{
    public int Id { getset; }
    public string Name { getset; }

    public override bool Equals(object obj)
    {
        if (obj is Test other)
        {
            return this.Id == other.Id && this.Name == other.Name;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return (Id, Name).GetHashCode();
    }
}

3. 重載 == 操作符

有時候,我們更傾向于使用 == 操作符來比較對象,為了讓你的代碼看起來更加自然,不妨重載一下這個操作符吧!

注意,重載 == 操作符時,通常也要重載 != 操作符

public class Test
{
    public int Id { getset; }
    public string Name { getset; }

    public static bool operator ==(Test left, Test right)
    {
        if (left is null && right is nullreturn true;
        if (left is null || right is nullreturn false;
        return left.Equals(right);
    }

    public static bool operator !=(Test left, Test right)
    {
        return !(left == right);
    }

    public override bool Equals(object obj)
    {
        return obj is Test other && Equals(other);
    }

    public override int GetHashCode()
    {
        return (Id, Name).GetHashCode();
    }
}

4. 利用匿名函數(shù)或 Lambda 表達(dá)式

如果你只是偶爾需要比較兩個對象,Lambda 表達(dá)式是個不錯的選擇,簡單又直接,快速搞定一切:

Test A = new Test { Id = 1, Name = "Test" };
Test B = new Test { Id = 1, Name = "Test" };

bool areEqual = A.Id == B.Id && A.Name == B.Name; // 手動比較屬性

5. 序列化為 Json 字符串再比較

如果你需要快速比較兩個復(fù)雜對象,可以考慮把它們序列化成 JSON 字符串然后進(jìn)行比較,這種方法雖然不是直接的對象比較方法,但簡單粗暴,在某些情況下能大顯身手。

序列化推薦使用 System.Text.Json(.NET 6 及之后的版本)或 Newtonsoft.Json(第三方庫)這兩個庫。

using System.Text.Json;

var jsonA = JsonSerializer.Serialize(A);
var jsonB = JsonSerializer.Serialize(B);

bool areEqual = jsonA == jsonB; // 比較 JSON 字符串

需要注意的是,這種方法對于復(fù)雜類型或含有大量嵌套對象的情況,性能和效率可能比較差。

6. 直接比較

雖然說大多數(shù)情況,兩個相同類型的對象之間不能直接比較,但 record 類型是個例外。

如果你使用的是 .NET 6 及之后的版本,并且對象的類型是 record 類型,那么恭喜你!

因為記錄類型默認(rèn)實(shí)現(xiàn)了 Equals 和 GetHashCode 方法,并且提供了 == 和 != 運(yùn)算符重載,使得比較變得非常簡單

public record Test(int Id,string Name);

// 創(chuàng)建兩個 Test 對象
Test a = new Test(1"test");
Test b = new Test(1"test");

// 比較兩個對象是否相等
bool areEqual = a == b; // 返回 true

7. 使用第三方庫

最后,當(dāng)然不能錯過各種強(qiáng)大的第三方庫,它們就像是你編程生活中的 "金牌助手" ,如果你懶得自己動手造輪子,它們會是你的最佳選擇,推薦幾個我常用的庫:

  • EqualityComparer,一個泛型類,可以用于比較兩個對象的相等性,例如:

    bool areEqual = EqualityComparer<Test>.Default.Equals(A, B);
  • Objects Comparer,它允許逐個成員遞歸地比較對象,并為某些屬性、字段或類型定義自定義比較邏輯,例如:

    var comparer = new ObjectsComparer<Test>;

    var test1 = new Test(1"test");
    var test2 = new Test(1"test"); 

    var isEqual = comparer.Compare(test1, test2); // 比較兩個對象
    ......
  • Compare.NET Objects,可以更詳細(xì)地獲取兩個對象之間的差異,并記錄具體的差別,例如:

    var test1 = new Test(1"test");
    var test2 = new Test(1"test");

    var propertyCount = 2;
    CompareLogic compareLogic = new CompareLogic()
    {
     Config = new ComparisonConfig()
     {
      MaxDifferences = propertyCount //MaxDifferences的默認(rèn)值是1
     } 
     
    };

    bool result = compareLogic.Compare(test1, test2).AreEqual;
    Console.Write(result);

以上只是一些簡單的例子,小伙伴們可以到這些第三方庫的官網(wǎng)解鎖更多使用姿勢!

總結(jié)

比較對象是編程中的一項基本技能,它幫助我們維護(hù)數(shù)據(jù)的和諧,提升業(yè)務(wù)邏輯的效率,確保應(yīng)用程序的正常運(yùn)行,希望這 7 個方法能夠讓你在面對比較對象的任務(wù)時游刃有余!

記得在比較之前處理好 null 的情況,以免出現(xiàn)空引用異常哦!


該文章在 2024/12/13 9:26:22 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊、財務(wù)費(fèi)用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
色欧美4477福利网在线观看 | 亚洲人成网站高清观看 | 亚洲自拍r级免费视频 | 亚洲综合中文字线观看看 | 亚洲国产日韩在线人成蜜芽 | 日韩二区三区久久久 |