如何在 C#8 中使用 GUID
譯文鏈接:https://www.infoworld.com/article/3539951/how-to-work-with-guids-in-csharp-8.html
在程序開發(fā)中經(jīng)常會用到 GUID (全球唯一標(biāo)志符) 的場景,GUID 就像數(shù)據(jù)庫中的主鍵,它能夠確保一些非常重要的信息,比如說:客戶數(shù)據(jù)或發(fā)票不會出現(xiàn)重復(fù)或者數(shù)據(jù)被覆蓋,如果沒有GUID的話,你很難保證數(shù)據(jù)不丟失以及數(shù)據(jù)的完整性。
本質(zhì)上來說,GUID就是一串很長的編號,這串編號從數(shù)學(xué)角度能夠保證不僅僅在一個系統(tǒng)中是唯一的,而且在多系統(tǒng)甚至跨系統(tǒng)之間都是唯一的,這篇文章我們就來討論一下為什么需要GUID,以及如何在 C#8 中使用 GUID。
要想運(yùn)行本篇提供的例子,你需要安裝 Visual Studio 2019,如果沒有的話,可以到官網(wǎng)去下載。
為什么要用 GUID
想象一下如果你有一個銷售性質(zhì)的app手機(jī)程序,它可以工作于離線和在線兩種模式,假定你的程序所生成的訂單ID是從1開始遞增的,當(dāng)你的應(yīng)用程序在離線狀態(tài)下生成了一些銷售訂單數(shù)據(jù),一旦聯(lián)網(wǎng)之后,這些重復(fù)的訂單ID如何進(jìn)行合并,不用想肯定會存在沖突的,對吧,所以你要做的事情就是完全做到訂單ID的唯一性,而不是為了這個情況不得不寫很多的代碼來妥協(xié)。
接下來看一下 GUID 是如何解決這種問題的,GUID 是一個很長的編號,有128bit位,幾乎可以說是獨(dú)一無二的,這里我為什么要加上幾乎呢?雖然GUID是一個很長的編號,它的沖突微乎其微,但不代表這種可能性為 0 。
你可以把 GUID 作為你數(shù)據(jù)表的主鍵,這樣你也不用怕當(dāng)有多個 數(shù)據(jù)庫 做合并的時候產(chǎn)生主鍵沖突,因?yàn)楦揪筒粫l(fā)生,而且在 離線狀態(tài) 下,你也可以大大方方的使用 GUID 來生成銷售訂單,不需要去連接什么內(nèi)網(wǎng)和外網(wǎng)。
GUID 的組成分析
下面就是一個 GUID 的例子,值得注意的是 GUID 通常是128bit,為了方便閱讀一般都用 16進(jìn)制表示。
eaa24756-3fac-4e46-b4bb-074ff4f5b846
GUID 是一個約定為 32 個16進(jìn)制組成的,這些16進(jìn)制數(shù)字由 8-4-4-12 分四塊進(jìn)行編碼的,大家可以仔細(xì)對照上面的GUID格式,因此最多有 2^128 個 GUID。
使用 C#8 生成GUID
這一部分將會學(xué)習(xí)如何使用 C# 創(chuàng)建 GUID,你可以使用 System 命名空間下的結(jié)構(gòu)體 Guid,這是生成 Guid 最直接的一個方式,可以像下面代碼那樣在 Main 方法中生成GUID。
Guid?obj?=?Guid.NewGuid();
Console.WriteLine("The?newly?created?Guid?is:?"?+?obj.ToString());
Console.ReadKey();
使用 C#8 生成一個空的 GUID
因?yàn)镚UID是一個結(jié)構(gòu)體,所以它肯定是一個值類型,但是值類型你不可以給它設(shè)置為null,意思就是,如果你想生成一個空GUID,你可以如下這么寫:
Guid?id?=?new?Guid();
if(id?==?Guid.Empty)
Console.WriteLine("The?Guid?is?empty");
空的GUID的值是:00000000-0000-0000-0000-000000000000,你可以利用這個值去判斷另一個GUID 是否為空,對吧,代碼如下:
if?(guid?!=?Guid.Empty){??
??//The?GUID?object?contains?non-zero?values
}
else
{
??//The?GUID?object?is?empty
}?
下面我寫了一個簡單的擴(kuò)展方法,用于判斷指定的 GUID 是否為空。
public?static?bool?IsNullOrEmpty(this?Guid?guid)
{
??return?(guid?==?Guid.Empty);
}?
如果你想判斷一個可空類型的GUID是否為null,可以用下面的擴(kuò)展方法。
public?static?bool?IsNullOrEmpty(this?Guid??guid)
{
??if?(guid.HasValue)
????if?(guid?==?default(Guid))
????????return?true;
????return?false;
}
值得注意的是,default(Guid) 和 Guid.Empty 兩者是等價的。
C#8 中如何將 GUID 轉(zhuǎn)為 string
你甚至可以將 GUID 轉(zhuǎn)成一個 string 值,下面的代碼片段展示了如何將一個 空GUID 轉(zhuǎn)成 string 的過程。
string?str?=?Guid.Empty.ToString();
Console.WriteLine(str);
在使用GUID 的過程中有一點(diǎn)要注意,你除了會遇到極小概率的沖突,更要注意的是GUID 會占用更多的存儲空間和它的生成無序性,其實(shí)你也可以變通實(shí)現(xiàn),比如使用兩個 Ulong 總共128bit 并且有序的遞增它實(shí)現(xiàn)一個編程性質(zhì)的唯一GUID。
如果你想把 GUID 綁定到你的數(shù)據(jù)控件或者用戶界面,你可以將 GUID 轉(zhuǎn)成 String形式,甚至可以將 GUID 按照你的想要的格式進(jìn)行 ToString。
你也可以通過其他的方式生成一個 GUID,比如說:隨機(jī)數(shù),基于時間,基于硬件,基于內(nèi)容(比如:MD5,SHA-1),在后面的文章中我會帶著大家用這些方法是去實(shí)現(xiàn)以及更多GUID的高級功能。
