Contents

C# Enum 小記

最近從 Java 轉戰到 C# ,最近使用 Enum 發現還滿好用的,但跟 Java 不一樣。這邊整理一下。
之前 Java 的 Enum 筆記文章可以看Java 使用 Enum 小記 | 程式狂想筆記

重點

  1. Enum 裡面的屬性不能放字串資料
  2. Enum 屬性可以指定其他數字,後面屬性會自動累加前面數字
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public enum Days
{
	None,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday ,
	Saturday,
	Sunday,
}

等於下面

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public enum Days
{
	None = 0,
	Monday = 1,
	Tuesday = 2,
	Wednesday = 3,
	Thursday = 4,
	Friday = 5,
	Saturday = 6,
	Sunday = 7,
}

大概就這樣,有想到再寫。

強轉型問題程式不會錯

最近Web 把 request 其中一個屬性定義一個 Enum。沒想到前端送一個參數(Enum)沒帶 Enum內數字,執行程式竟然不會出錯,我就開始針對這個問題研究。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var b = (Season)1;
Console.WriteLine(b);  // output: Summer

var c = (Season)4;


Console.WriteLine(c);  // output: 4
public enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

針對任何列舉類型,列舉型別與其基礎整數類型之間有明確的轉換。 如果您將列舉值 轉換成 其基礎類型,結果就是列舉成員的相關聯整數值。

微軟官方文件也有寫到,參考:列舉型別 - C# 參考 | Microsoft Learn

這邊我有試著問 AI有得到答案。
https://i.imgur.com/PvAlXJ0.png
https://i.imgur.com/N0Pa4Zy.png

檢查是否符合 Enum 資料

怎麼檢查符合資料,ChatGPT AI 怎麼回答

https://i.imgur.com/0GUSQP6.png
https://i.imgur.com/VQeh17d.png
https://i.imgur.com/8M0KUvf.png

驗證上面方法可以使用。剛好最後爬到官方文件有提到,不過篇幅沒有AI說的多。

Web 檢查方法

1
2
            [EnumDataType(typeof(DataSyncTypeEnum),ErrorMessage ="未正常抓到")]
            public DataSyncTypeEnum ReqVerType { get; set; } = DataSyncTypeEnum.Index;

一般檢查方法

Enum.IsDefined 可以參考 列舉型別 - C# 參考 | Microsoft Learn

FlagsAttribute

在微軟文件有看到[Flags]可以把值表示Byte來處理。這邊官方文張其實有講差異,但沒仔細看就會忽略掉。

如果您想要列舉型別代表選項的組合,請定義這些選擇的列舉成員,讓個別選擇是位欄位。 也就是說,這些列舉成員的關聯值應該是兩個的乘冪。 然後,您可以使用位邏輯運算子 | ,或 &分別結合選擇或交集選擇的組合。 若要指出列舉型別會宣告位欄位,請將 Flags 屬性套用至它。 如下列範例所示,您也可以在列舉型別的定義中包含一些典型的組合。

這邊我就簡單問個 AI 問題。

https://i.imgur.com/po2W3Df.png
這邊AI給的範例很實用,代表這個列舉可以用兩個組合,這邊注意 enum 裡面的所有值必須手動給0,1,2,4,8,16,32,64。這邊後面會在講原因。

https://i.imgur.com/L3epYfn.png

這邊他範例有點爛。我後來發現官方文件也是用星期當範例😅。想跟他要比較符合情境,讓我覺得這個可以用在實務上面。

https://i.imgur.com/uDs5h4D.png

最後 AI 給我答案讓我覺得真的很棒。HasFlag可以做判斷

不要使用 Enum.IsDefined 方法驗證參數?

首先我看到這篇討論有提到不要使用 Enum.IsDefined

Regarding Enum.IsDefined, be aware that it can be dangerous: msdn.microsoft.com/en-us/library/ms229025(VS.90).aspx – 
adrian
I prefer this definition: “Returns an indication whether a constant with a specified value exists in a specified enumeration” from MSDN

其實我原本都看不太懂。這邊我就去問 AI 大神。

https://i.imgur.com/jECaHvq.png

我突然恍然大悟。

https://i.imgur.com/luILUPb.png https://i.imgur.com/nYXKVqC.png
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Days day = Days.Monday | Days.Thursday;

//day.HasFlag(Days.Thursday).Dump();	
Enum.IsDefined(typeof(Days),day).Dump();

day.Dump();

[Flags]
public enum Days
{
	None,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday ,
	Saturday,
	Sunday
}

其實[Flags]可以省略,還有我這邊也沒有給數值0,1,2,4,8,16,32,64。因為這樣Enum.IsDefined這會得出錯誤結果。

透過 AI 老師讓我了解這個東西。XD

FlagsAttribute 複合屬性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Flags]
public enum Permissions
{
	None = 0,
	Read = 1,
	Write = 2,
	Execute = 4,
	ReadWrite = Read | Write,       // (1|2) => 1+2 = 3
	ReadExecute = Read | Execute,   // (1|4) => 1+4 = 5
	WriteExecute = Write | Execute, // (2|4) => 2+4 = 6
	All = Read | Write | Execute    // (1|2|4) => 1+2+4 = 7
}
Note

看起來(1|2) 運算很簡單,這邊其實是用2進去去做換算,建議可以去看電子計算機概論就能知道這邊在做什麼。

(1|2) => 1+2 = 3
這邊做二進位換算
01 => 1
10 => 2
-–
11 => 3

(1|4) => 1+4 = 5
這邊做二進位換算
001 => 1
100 => 4
-–
101 => 5

AI 給了很棒範例,他也說過1|2等於1+2。這個設計很已把很多狀態融合在一起,這樣一個 Entity 不需要有這麼多狀態欄位,我覺得這個可以用在檔案權限、帳號權限,也可以依照特別物件做設計。

使用 AI 心得

有幾篇看不是很懂,但透過 AI 回答東西,我再去驗證思考過他是否說的是正確,在一部相關文件可能都能對應,畢竟有些是翻譯或語言問題,通常第一眼看可能看不出意思,但透過 AI 說的,我們去重看文章很能就能知道問題了。

其它可參考文章