Roses/Assets/Scripts/Extensions/SmartEnum.cs
2024-04-17 18:01:33 +02:00

49 lines
No EOL
1.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Extensions {
public abstract class SmartEnum<TEnum, TValue> where TEnum : SmartEnum<TEnum, TValue> {
private static readonly List<TEnum> _list = new();
// Despite analysis tool warnings, we want this static bool to be on this generic type (so that each TEnum has its own bool).
private static bool _invoked;
public static List<TEnum> List {
get {
if (!_invoked) {
_invoked = true;
// Force invocaiton/initialization by calling one of the derived members.
typeof(TEnum).GetProperties(BindingFlags.Public | BindingFlags.Static)
.FirstOrDefault(p => p.PropertyType == typeof(TEnum))?.GetValue(null, null);
}
return _list;
}
}
public string Name { get; }
public TValue Value { get; }
protected SmartEnum(string name, TValue value) {
Name = name;
Value = value;
TEnum item = this as TEnum;
List.Add(item);
}
public static TEnum FromName(string name) {
return List.Single(item => string.Equals(item.Name, name, StringComparison.OrdinalIgnoreCase));
}
public static TEnum FromValue(TValue value) {
// Can't use == to compare generics unless we constrain TValue to "class", which we don't want because then we couldn't use int.
return List.Single(item => EqualityComparer<TValue>.Default.Equals(item.Value, value));
}
public override string ToString() => $"{Name} ({Value})";
public static implicit operator TValue(SmartEnum<TEnum, TValue> key) => key.Value;
}
}