using System.Collections.Concurrent;
using System.Globalization;
namespace MeloongCore;
public static class EnumUtils {
///
/// 获取枚举的所有值。
///
private static IEnumerable GetAllValues() where T : struct, Enum
=> Enum.GetValues(typeof(T)).Cast();
///
/// 对于具有 的枚举,返回其所有 Flag 值。
/// 建议仅对没有极端值的正数枚举使用。
///
///
/// 会跳过:0、非 2 的幂的值、不在枚举值中的数、组合值、对应同一个枚举项的多个别名。
///
public static List GetAllFlags() where T : struct, Enum {
if (allFlagsCache.TryGetValue(typeof(T), out var cached)) return cached.Cast().ToList();
if (!typeof(T).IsDefined(typeof(FlagsAttribute), inherit: false)) throw new ArgumentException($"枚举 {typeof(T).FullName} 没有定义 FlagsAttribute。");
var flags = new List();
foreach (var element in EnumUtils.GetAllValues().Distinct()) {
var number = Convert.ToInt64(element, CultureInfo.InvariantCulture);
if (number == 0 || (number & (number - 1)) != 0) continue; // 跳过 0 和非 2 的幂的值
flags.Add(element);
}
allFlagsCache[typeof(T)] = flags.Cast().ToList();
return flags;
}
private static readonly ConcurrentDictionary> allFlagsCache = new();
}