Skip to content

Instantly share code, notes, and snippets.

@karenpayneoregon
Created January 29, 2024 16:05
Show Gist options
  • Save karenpayneoregon/e3e2d4be50478abbf1bbb0bb657528c0 to your computer and use it in GitHub Desktop.
Save karenpayneoregon/e3e2d4be50478abbf1bbb0bb657528c0 to your computer and use it in GitHub Desktop.
Enum helpers

Provides several methods for working with enum with C#

public enum BookCategories
{
[Description("Options")]
[Display(Name = "Select")]
Select = 0,
[Description("Space Travel")]
[Display(Name = "Space Travel")]
SpaceTravel = 1,
[Description("Adventure")]
[Display(Name = "Adventure")]
Adventure = 2,
[Description("Popular sports")]
[Display(Name = "Popular sports")]
Sports = 3,
[Description("Cars")]
[Display(Name = "Cars")]
Automobile = 4,
[Description("Programming with C#")]
[Display(Name = "Programming with C# 12")]
Programming = 5
}
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
namespace TODO.Classes;
public static class Enums
{
public static List<T> ToList<T>()
{
var enumType = typeof(T);
if (enumType.BaseType != typeof(Enum))
{
throw new ArgumentException($"T must be of type System.Enum");
}
var enumArray = Enum.GetValues(enumType);
List<T> list = new(enumArray.Length);
list.AddRange(enumArray.Cast<int>().Select(x => (T)Enum.Parse(enumType, x.ToString())));
return list;
}
public static string DisplayName(this Enum sender)
{
return sender.GetType()
.GetMember(sender.ToString())
.First()
.GetCustomAttribute<DisplayAttribute>()!
.GetName();
}
public static List<KeyValuePair<string, Enum>> DescriptionAsDictionary<T>() =>
Enum.GetValues(typeof(T)).Cast<T>()
.Cast<Enum>()
.Select(value => new KeyValuePair<string, Enum>(
(Attribute.GetCustomAttribute(value.GetType().GetField(value.ToString())!,
typeof(DescriptionAttribute)) as DescriptionAttribute)!.Description, value))
.ToList();
}
List<BookCategories> categories = Enums
.ToList<BookCategories>();
var descriptions = categories
.Select((category,index) => new {Value = category, Index = index})
.ToList();
List<KeyValuePair<string, Enum>> dictionary = Enums.DescriptionAsDictionary<BookCategories>();
Debug.WriteLine(BookCategories.Programming.DisplayName());
Debug.WriteLine("");
descriptions.ForEach(x => Debug.WriteLine($"{x.Index,-4}{x.Value}"));
Debug.WriteLine("");
dictionary.ForEach(x => Debug.WriteLine($"{x.Key,-22}{x.Value}"));
@bitm0de
Copy link

bitm0de commented Jul 12, 2024

Wouldn't it be better to use generic constraints for type-safety and not worry about the cast in the first place potentially failing from using this method on a non-Enum? I would also probably use a real generic dictionary as it would be an odd case to have two or more of the exact same description since that would defeat the point in most use cases (i.e. keys we can assume are distinct). Alternatively, a better method name than DescriptionAsDictionary might be DescriptionAsMappings if the value isn't a bucket/collection of related enum values with the same description.

public static IReadOnlyDictionary<string, TEnum> GetDescriptions<TEnum>() where TEnum : struct, Enum
    => Enum.GetValues<TEnum>()
        .ToDictionary(x => typeof(TEnum).GetField(x.ToString())!.GetCustomAttribute<DescriptionAttribute>()!.Description, x => x);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment