Skip to content

Instantly share code, notes, and snippets.

@jhlee8804
Last active June 3, 2023 02:07
Show Gist options
  • Save jhlee8804/535ff79c69d8cf2b1b6cb5ab502141be to your computer and use it in GitHub Desktop.
Save jhlee8804/535ff79c69d8cf2b1b6cb5ab502141be to your computer and use it in GitHub Desktop.
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace System
{
public static class EnumExtensions
{
private static readonly ConcurrentDictionary<string, string> _enumToValueMap
= new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private static readonly ConcurrentDictionary<string, object> _valueToEnumMap
= new ConcurrentDictionary<string, object>();
/// <summary>
/// enum에 <see cref="EnumMemberAttribute"/>로 선언된 속성이 있다면 <see cref="EnumMemberAttribute.Value"/>를 반환한다.
/// 선언된 속성이 없다면 enum명을 그대로 반환한다.
/// </summary>
public static string ToEnumMemberString(this Enum self)
{
var enumType = self.GetType();
var enumName = Enum.GetName(enumType, self);
var key = $"{enumType.FullName}.{enumName}";
return _enumToValueMap.GetOrAdd(key, _ =>
{
var enumMemberAttr = ((EnumMemberAttribute[])enumType.GetField(enumName)
.GetCustomAttributes(typeof(EnumMemberAttribute), true))
.SingleOrDefault();
return (enumMemberAttr != null) ? enumMemberAttr.Value : enumName;
});
}
/// <summary>
/// <see cref="EnumMemberAttribute.Value"/>로 선언된 string을 <see cref="Enum"/>으로 파싱하여 반환한다.
/// 선언된 속성이 없다면 <see cref="Enum.Parse(Type, string)"/>로 시도한다.
/// </summary>
public static T ParseEnumMember<T>(string value, bool ignoreCase = true)
{
var enumType = typeof(T);
var key = $"{enumType.FullName}.{value}";
return (T)_valueToEnumMap.GetOrAdd(key, _ =>
{
foreach (string name in Enum.GetNames(enumType))
{
var enumMemberAttr = ((EnumMemberAttribute[])enumType.GetField(name)
.GetCustomAttributes(typeof(EnumMemberAttribute), true))
.SingleOrDefault();
if (enumMemberAttr != null && enumMemberAttr.Value == value)
{
return Enum.Parse(enumType, name);
}
}
return Enum.Parse(enumType, value, ignoreCase);
});
}
/// <summary>
/// <see cref="EnumMemberAttribute.Value"/>로 선언된 string을 <see cref="Enum"/>으로 파싱하여 반환한다.
/// 선언된 속성이 없다면 <see cref="Enum.Parse(Type, string)"/>로 시도한다.
/// </summary>
public static bool TryParseEnumMember<T>(string value, out T result, bool ignoreCase = true)
{
if (value.IsNullOrWhiteSpace())
{
result = default(T);
return false;
}
result = ParseEnumMember<T>(value, ignoreCase);
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment