using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.Serialization;
public static class FlagParser
public static bool Parse(string value) {
return Parse(value, false);
public static bool Parse(string value, bool defaultValue) {
return TryParse(value).GetValueOrDefault(defaultValue);
public static bool? TryParse(string value) {
if ("1" == value || bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase) || "Y".Equals(value, StringComparison.OrdinalIgnoreCase)) {
if ("0" == value || bool.FalseString.Equals(value, StringComparison.OrdinalIgnoreCase) || "N".Equals(value, StringComparison.OrdinalIgnoreCase)) {
public enum AccessControlType
[EnumMember(Value = "allow")]
[EnumMember(Value = "deny")]
private static readonly ConcurrentDictionary<Type, Tuple<IDictionary<string, MemberInfo>, IDictionary<string, string>>> Cache = new ConcurrentDictionary<Type, Tuple<IDictionary<string, MemberInfo>, IDictionary<string, string>>>();
internal class MemberInfo
public string EnumMemberValue {
public string GetValue() {
return HasEnumMember ? EnumMemberValue : Name;
public bool HasEnumMember => !string.IsNullOrEmpty(EnumMemberValue);
internal static Tuple<IDictionary<string, MemberInfo>, IDictionary<string, string>> GetEnumMap(Type enumType) {
return Cache.GetOrAdd(enumType, type => {
var list = Enum.GetNames(enumType)
.Select(x => new MemberInfo {
EnumMemberValue = enumType.GetRuntimeField(x)?.GetCustomAttributes(typeof(EnumMemberAttribute), false).OfType<EnumMemberAttribute>().FirstOrDefault()?.Value
return Tuple.Create<IDictionary<string, MemberInfo>, IDictionary<string, string>>(
new SortedDictionary<string, MemberInfo>(
list.ToDictionary(x => x.Name, x => x), StringComparer.OrdinalIgnoreCase),
new SortedDictionary<string, string>(
list.ToDictionary(x => x.GetValue(), x => x.Name), StringComparer.OrdinalIgnoreCase));
public static T? ParseEnum<T>(string value)
if (!string.IsNullOrEmpty(value)) {
if (int.TryParse(value, out var valueInt32)) {
result = (T) Enum.ToObject(typeof(T), valueInt32);
if (Enum.TryParse(value, true, out T valueEnum)) {
} else if (!value.Contains(",")) {
var map = GetEnumMap(typeof(T)).Item2;
if (map.TryGetValue(value, out var name)) {
result = (T?) Enum.Parse(typeof(T), name, false);
public static void Main()
Console.WriteLine($"Parse null: {(FlagParser.TryParse(null)?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse 0: {(FlagParser.TryParse("0")?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse 1: {(FlagParser.TryParse("1")?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse false: {(FlagParser.TryParse("false")?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse true: {(FlagParser.TryParse("true")?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse allow: {(FlagParser.TryParse("allow")?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse deny: {(FlagParser.TryParse("deny")?.ToString() ?? "<null>")}");
Console.WriteLine($"Parse allow: {(ParseEnum<AccessControlType>("allow") ?? AccessControlType.Allow)}");
Console.WriteLine($"Parse deny: {(ParseEnum<AccessControlType>("deny") ?? AccessControlType.Allow)}");
Console.WriteLine($"Parse allow: {(ParseEnum<AccessControlType>("0") ?? AccessControlType.Allow)}");
Console.WriteLine($"Parse deny: {(ParseEnum<AccessControlType>("1") ?? AccessControlType.Allow)}");