0.介紹
枚舉是一組命名常量,其基礎類型為任意整型。 如果沒有顯式聲明基礎類型, 則為Int32
在實際開發過程中,枚舉的使用可以讓代碼更加清晰且優雅。
最近在對枚舉的使用進行了一些總結與整理,也發現了一些很有意思的知識盲區。
接下來先簡單為大家介紹枚舉在開發過程中的常用內容以及擴展類的分享。如果喜歡直接看代碼的可以查看最后的樣例源碼。
1. 參考資料
官方Doc https://docs.microsoft.com/zh-cn/dotnet/api/system.enum?view=net-5.0
博客 https://www.cnblogs.com/kissdodog/archive/2013/01/16/2863515.html
博客 https://www.cnblogs.com/willick/p/csharp-enum-superior-tactics.html
2.核心內容
-
枚舉的使用心得
0.枚舉數值在開發過程中一旦確定不允許更改(除非必要 )
1.在定義枚舉的時候要設置0值,且不作為有效的業務值。(不作為有效值的原因是枚舉的初始化值為零,在沒有正確賦值的情況下,已經有默認值可能會造成困擾,所以直接不使用0作為業務有效值,可以省去不必要的麻煩,這半點純屬個人建議~)
這一點官方文檔也有“最佳做法”的建議。
如果未定義值為0的枚舉成員,則考慮創建 None 枚舉常數。 默認情況下,由公共語言運行時將用於枚舉的內存初始化為零。 因此,如果未定義值為零的常量,則在創建枚舉時將包含非法值。
2.在前后端交互過程中,如果后端接收的對象中包含枚舉的話,需要將枚舉屬性定義成可空枚舉,否則前端數據有可能(前端屬性值在后端的枚舉值中匹配不上時)無法傳輸到后端。
3.數據庫保存枚舉值而非枚舉屬性字符串
雖然保存枚舉屬性字符串會更加直觀,但是不利於后續枚舉字符串重命名,且字符串長度限制也制約着枚舉的命名...
-
枚舉的基本用法
定義枚舉
枚舉並不顯式從繼承 Enum ; 繼承關系由編譯器隱式處理
// 枚舉YesOrNo
public enum YesOrNo
{
[Description("")]
None = 0,
[Description("是")]
Yes = 1,
[Description("否")]
No = 2
}
// 枚舉YesOrNo 基礎類型為byte
public enum YesOrNo_Byte : byte
{
[Description("")]
None = 0,
[Description("是")]
Yes = 1,
[Description("否")]
No = 2
}
枚舉 => 轉字符串
string yesString = YesOrNo.Yes.ToString(); // Yes
枚舉 => 轉數字
int yesInt = (int)YesOrNo.Yes; // 1
字符串 => 枚舉
YesOrNo yesOrNo_Yes = (YesOrNo)Enum.Parse(typeof(YesOrNo), "Yes"); // YesOrNo.Yes
數字 => 枚舉
YesOrNo yesOrNo_No = (YesOrNo)2; // YesOrNo.No
獲取所有的枚舉成員
Array yesOrNos = Enum.GetValues(typeof(YesOrNo)); // [YesOrNo.None,YesOrNo.Yes,YesOrNo.No]
獲取所有枚舉成員的屬性名
string[] yesOrNoNames = Enum.GetNames(typeof(YesOrNo)); // ["None","Yes","No"]
獲取枚的舉基礎類型
Type typeInt = Enum.GetUnderlyingType(typeof(YesOrNo)); // System.Int32
Type typeByte = Enum.GetUnderlyingType(typeof(YesOrNo_Byte)); // System.Byte
-
擴展方法
字符串 => 轉枚舉
// GetEnum() 字符串 => 轉枚舉
var yesString = "Yes".GetEnum<YesOrNo>(); // YesOrNo.Yes
/// <summary>
/// 根據字符串轉成指定枚舉值
/// </summary>
public static T GetEnum<T>(this string enumString)
{
return (T)Enum.Parse(typeof(T), enumString);
}
枚舉 => 轉數字
// GetIntValue() 枚舉 => 轉數字
int yesInt = YesOrNo.Yes.GetIntValue(); // 1
/// <summary>
/// 獲取枚舉的值
/// </summary>
public static int GetIntValue(this Enum value)
{
return Convert.ToInt32(value);
}
獲取枚舉的描述
// GetDescription() 獲取枚舉的描述
var description = YesOrNo.Yes.GetDescription(); // 是
/// <summary>
/// 根據枚舉獲取枚舉描述
/// </summary>
public static string GetDescription(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
if (customAttribute == null)
return value.ToString();
else
return ((DescriptionAttribute)customAttribute).Description;
}
將枚舉字符串值與描述轉字典
// GetEnumDescriptions() 獲取枚舉字符串值與描述
var dictionary = typeof(YesOrNo).GetEnumDescriptions(); // {{[None, ""]},{[Yes, 是]},{[No, 否]}}
/// <summary>
/// 獲取枚舉字符串值及描述值的字典
/// </summary>
public static IDictionary<string, string> GetEnumDescriptions(this Type enumType)
{
var dictionary = new Dictionary<string, string>();
foreach (Enum code in Enum.GetValues(enumType))
dictionary.Add(code.ToString(), code.GetDescription());
return dictionary;
}
將枚舉值與描述轉字典
// GetEnumIntDescriptions() 獲取枚舉值與描述
var intDictionary = typeof(YesOrNo).GetEnumIntDescriptions(); // {{[0, ""]},{[1, 是]},{[2, 否]}}
/// <summary>
/// 獲取枚舉值及描述值的字典
/// </summary>
public static IDictionary<int, string> GetEnumIntDescriptions(this Type enumType)
{
var dictionary = new Dictionary<int, string>();
foreach (Enum code in Enum.GetValues(enumType))
dictionary.Add(code.GetIntValue(), code.GetDescription());
return dictionary;
}