//// 定義一個 string 的擴充方法來處理 字串資料轉 FlagEnum publicstaticclassStringExtension { //// 泛型處理挺麻煩 (( 汗 publicstatic T ToFlagEnum<T>(thisstring jsonArrayOrString) where T : struct, Enum { string[] items; try{ items = JsonSerializer.Deserialize<string[]>(jsonArrayOrString); } catch{ items = jsonArrayOrString.Split(',',StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); } //// 因為是泛型的關係,編譯期間是無法得知 Enum 底層的數值是什麼型別 //// 因此需要先轉換成底層數數值型別才能做位元運算 (byte , int, short...) var underLyingPrimitiveType = Enum.GetUnderlyingType(typeof(T)); var result = Convert.ChangeType(0,underLyingPrimitiveType);
//// 接著對傳入值一樣解析成數值型別 //// 對齊後 處理位元運算 foreach(var item in items) { if (Enum.TryParse<T>(item, ignoreCase : false, outvarvalue)) { var parsedEnumValue = Convert.ChangeType(value,underLyingPrimitiveType); result = underLyingPrimitiveType switch { Type t when t == typeof(byte) => (byte)result | (byte)parsedEnumValue, Type t when t == typeof(sbyte) => (sbyte)result | (sbyte)parsedEnumValue, Type t when t == typeof(short) => (short)result | (short)parsedEnumValue, Type t when t == typeof(ushort) => (ushort)result | (ushort)parsedEnumValue, Type t when t == typeof(int) => (int)result | (int)parsedEnumValue, Type t when t == typeof(uint) => (uint)result | (uint)parsedEnumValue, Type t when t == typeof(long) => (long)result | (long)parsedEnumValue, Type t when t == typeof(ulong) => (ulong)result | (ulong)parsedEnumValue, _ => thrownew NotSupportedException($"不支援的 enum 底層型別:{parsedEnumValue}") }; } } //// 最後記得,在轉回 Enum 類型! return (T)Enum.ToObject(typeof(T),result); } }
voidMain() { var jsonArray = "[\"Read\",\"Execute\"]"; jsonArray.ToFlagEnum<Permission>().Dump(); }