CODE-enum, string, int間的轉換
4 |
專案剛好用到列舉型別(enum)的處理,之前雖已寫過一篇相關文章,但這次又多用到了找上下筆及列出清單的特性,索性再整理一篇更完整的。
以下示範列出所有列舉項目及對應數值、字串、整數與列舉間的雙向轉換寫法,還有尋找上一個、下一個列舉值的簡陋做法(很不嚴謹,僅為示意,想深入研究的人這裡有個LINQ範例可參考)。注意: 字串轉列舉無對應時會有Exception,數字轉列舉無對應值時不會出錯而是出現未列舉宣告值的數字。(列舉居然可以出現非預先設定範圍內的值,不就打破了其存在的意義? 這點始終讓我很狐疑)
using System;
public class CSharpLab
{
public enum State
{
Init, Open, Proc, Close, Done = 9
}
public static void Test()
{
State st = State.Init;
//列出所有名稱
foreach (string en in Enum.GetNames(typeof(State)))
Console.WriteLine("Enum Name: " + en);
//列舉背後有值, 預設由零開始排, 但也可自訂
//TIPS: typeof(State)與st.GetType()都可取得列舉型別
foreach (int v in Enum.GetValues(st.GetType()))
Console.WriteLine("Enum Value: " + v.ToString());
//將列舉轉為字串
Console.WriteLine("Enum To String: " + st.ToString());
//將字串轉為列舉
st = (State)Enum.Parse(typeof(State), "proc", true);
Console.WriteLine("String To Enum: " + st);
try {
Console.WriteLine("String To Enum(not found): " +
Enum.Parse(typeof(State), "WTF"));
} catch (Exception ex) {
Console.WriteLine("Error when Enum.Parse: " + ex.Message);
}
//將列舉轉為數字
Console.WriteLine("Enum to Int: " + st + " " + (int)st);
//將數字轉回列舉
st = (State)9;
Console.WriteLine("Int to Enum: " + st);
//小心數字轉換對不上時不會有錯誤,但會出現非列舉值
st = (State)100;
Console.WriteLine("Int(100) to Enum: " + st);
//如果數字有連續,可以用+1, -1找上一個下一個
//注意: 以下範例並未檢查邊界及數值不連續的狀況,
//並非嚴謹寫法,僅為簡單示意,勿用於正式用途
st = State.Proc;
State next = (State)((int)st)+1;
State prev = (State)((int)st)-1;
Console.WriteLine("Now = " + st + " Next = " + next + " Prev = " + prev);
}
}
執行結果如下(以上程式可用Mini C# Lab直接執行),橘色為字串轉換無法對映的狀況,綠色為數字轉換無法對映的狀況。
Enum Name: Init
Enum Name: Open
Enum Name: Proc
Enum Name: Close
Enum Name: Done
Enum Value: 0
Enum Value: 1
Enum Value: 2
Enum Value: 3
Enum Value: 9
Enum To String: Init
String To Enum: Proc
Error when Enum.Parse: Requested value 'WTF' was not found.
Enum to Int: Proc 2
Int to Enum: Done
Int(100) to Enum: 100
Now = Proc Next = Close Prev = Open
最後補充一個用法,enum可以加上[Flags]宣告,再將各值設成0x01, 0x2, 0x4, 0x8...,就可以當成旗標用myFlags = MyEnum.Flag1 | MyEnum.Flag2的方式操作,myFlags.ToString()時會傳回Flag1, Flag2。MSDN上有完整的範例,這裡不再贅言。
Comments
# by 大估
大估會在Enum的列舉值中,加上Description,放入對應的字串 例子如下… Public Enum FlowSignAnser <Description("同意")> Yes = 0 <Description("不同意")> No = 1 End Enum 再用下面這個Function抓值 Public Function glb_GetEnumDescription(ByVal EnumConstant As [Enum]) As String Dim Fi As FieldInfo = EnumConstant.GetType().GetField(EnumConstant.ToString()) Dim DescAttr() As DescriptionAttribute = DirectCast(Fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute()) If DescAttr.Length > 0 Then Return DescAttr(0).Description Else Return EnumConstant.ToString() End If End Function
# by Jeffrey
to 大估,這招不錯!! 我之前都得另外寫一個Mapper函數用switch case對照出各列舉的中文名稱。(筆記,沙沙沙...)
# by 小期
傳入整數不會出錯我想原因就是在旗標那部份 >> 最後補充一個用法,enum可以加上[Flags]宣告,再將各值設成0x01, 0x2, 0x4, 0x8...,就可以當成旗標用myFlags = MyEnum.Flag1 | MyEnum.Flag2的方式操作,myFlags.ToString()時會傳回Flag1, Flag2。MSDN上有完整的範例,這裡不再贅言。 因為們可以作以下的位元運算 MyEnum myFlags = MyEnum.Flag1 | MyEnum.Flag2 這樣他會得到結果 3 ,但 3 實際並不存在在 Enum 裡面,只是他同時代表著是 Flag1 及 Flag2 另外 Enum 其實他的型別預設就是 Integer ,所以他本來就可以存放 Integer 的任意數(在 VB.Net 宣告 Enum 後可以用 As 指定型態,目前手邊沒有 C# ,不確定 C# 是否相同!)
# by Jeffrey
to 小期,感謝你的補充。