Skip to content

Instantly share code, notes, and snippets.

@mrpmorris
Created May 6, 2022 08:16
Show Gist options
  • Save mrpmorris/70c0664c3ef9c4177fa6bb46ccff7b4d to your computer and use it in GitHub Desktop.
Save mrpmorris/70c0664c3ef9c4177fa6bb46ccff7b4d to your computer and use it in GitHub Desktop.
Cached lookups for enum [Description] attributes
using System.Collections.Concurrent;
namespace Whatever;
public static class EnumDescriptions
{
private readonly static ConcurrentDictionary<Type, EnumDescriptionsCache> Cache = new();
public static IEnumerable<KeyValuePair<Enum, string>> GetValuesAndDescriptions(Type enumType) =>
GetOrAdd(enumType).GetAll();
public static IEnumerable<KeyValuePair<TEnum, string>> GetValuesAndDescriptions<TEnum>()
where TEnum : Enum
=>
GetOrAdd(typeof(TEnum))
.GetAll()
.Select(x => new KeyValuePair<TEnum, string>((TEnum)x.Key, x.Value));
public static string GetDescription(Type enumType, Enum value) =>
GetOrAdd(enumType).GetDescription(value);
private static EnumDescriptionsCache GetOrAdd(Type enumType)
{
return Cache.GetOrAdd(
key: enumType ?? throw new ArgumentNullException(nameof(enumType)),
valueFactory: x => new EnumDescriptionsCache(x));
}
}
internal class EnumDescriptionsCache
{
private readonly Type EnumType;
private readonly Dictionary<Enum, string> ValueToDescriptionLookup = new();
public EnumDescriptionsCache(Type enumType)
{
EnumType = enumType ?? throw new ArgumentNullException(nameof(enumType));
if (!EnumType.IsEnum)
throw new ArgumentException("Must be an Enum type", paramName: nameof(EnumType));
foreach(Enum enumValue in Enum.GetValues(EnumType))
{
FieldInfo fieldInfo = enumValue.GetType().GetField(enumValue.ToString()!)!;
var descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
string description =
descriptionAttribute?.Description ?? fieldInfo.Name;
ValueToDescriptionLookup.Add(enumValue, description);
}
}
public string GetDescription(Enum value) => ValueToDescriptionLookup[value];
public IEnumerable<KeyValuePair<Enum, string>> GetAll() => ValueToDescriptionLookup;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment