Skip to content

Instantly share code, notes, and snippets.

@bh3605
Last active May 10, 2022 17:12
Show Gist options
  • Save bh3605/b17a005b29019f794dff80f1d0a167e4 to your computer and use it in GitHub Desktop.
Save bh3605/b17a005b29019f794dff80f1d0a167e4 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class TypeSafeEnum<T> where T : class
{
TypeSafeEnum(string name, T typeSafeEnum)
{
Name = name;
Enum = typeSafeEnum;
}
public static readonly TypeSafeEnum<T>[] Enums =
typeof(T) //Static Properties
.GetProperties(BindingFlags.Public | BindingFlags.Static)
.Where(x => x.PropertyType == typeof(T))
.Select(x => new TypeSafeEnum<T>(x.Name, (T)x.GetValue(null)))
.Union(typeof(T) //Static fields
.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(x => x.FieldType == typeof(T))
.Select(x => new TypeSafeEnum<T>(x.Name, (T)x.GetValue(null))))
.ToArray();
public static readonly IEnumerable<T> Values = Enums.Select(x => x.Enum).ToArray();
public string Name { get; }
public T Enum { get; }
}
public static class TypeSafeEnumExtensions
{
public static T ToTypeSafeEnum<T>(this string name) where T : class
{
return TypeSafeEnum<T>.Enums
.SingleOrDefault(x => x.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))?.Enum;
}
public static T ToTypeSafeEnum<T>(this string name, T defaultEnum) where T : class
{
return TypeSafeEnum<T>.Enums
.SingleOrDefault(x => x.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))?.Enum ?? defaultEnum;
}
}
public static class TypeSafeEnumValuesFromTypeNameRetriever
{
/// <summary>
/// Gets all the TypeSafeEnum Values for a given type name from a given assembly
/// </summary>
public static IEnumerable<object> Retrieve<TAnyTypeInTargetAssembly>(string name)
{
var enums = Assembly
.GetAssembly(typeof(TAnyTypeInTargetAssembly))
.GetExportedTypes()
.Where(x => x.IsClass)
.Where(x =>
x.Name.Equals(name, StringComparison.OrdinalIgnoreCase) ||
x.Name.Equals(name + "dto", StringComparison.OrdinalIgnoreCase))
.OrderBy(x => x.Name)
.Select(GetTypeSafeEnumValuesFor)
.Where(x => x != null)
.SingleOrDefault(x => ((ICollection) x).Count > 0);
return (IEnumerable<object>)enums ?? Enumerable.Empty<object>();
}
private static object GetTypeSafeEnumValuesFor(Type type)
{
var unboundTypeSafeEnumType = typeof(TypeSafeEnum<>);
var boundTypeSafeEnumType = unboundTypeSafeEnumType.MakeGenericType(type);
return boundTypeSafeEnumType
.GetField("Values", BindingFlags.Public | BindingFlags.Static)
?.GetValue(null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment