Следуя ответу @Even Mien, я попытался пойти немного дальше и сделать его универсальным, я, кажется, почти на месте, но один случай все еще сопротивляется, и я, вероятно, могу немного упростить свой код.
Я публикую это здесь, если кто-нибудь увидит, как я могу улучшить и особенно заставить его работать, поскольку я не могу назначить его из строки
Пока у меня есть следующие результаты:
Console.WriteLine(TestEnum.Test1);//displays "TEST1"
bool test = "TEST1" == TestEnum.Test1; //true
var test2 = TestEnum.Test1; //is TestEnum and has value
string test3 = TestEnum.Test1; //test3 = "TEST1"
var test4 = TestEnum.Test1 == TestEnum.Test2; //false
EnumType<TestEnum> test5 = "TEST1"; //works fine
//TestEnum test5 = "string"; DOESN'T compile .... :(:(
Где происходит волшебство:
public abstract class EnumType<T> where T : EnumType<T>
{
public string Value { get; set; }
protected EnumType(string value)
{
Value = value;
}
public static implicit operator EnumType<T>(string s)
{
if (All.Any(dt => dt.Value == s))
{
Type t = typeof(T);
ConstructorInfo ci = t.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,null, new Type[] { typeof(string) }, null);
return (T)ci.Invoke(new object[] {s});
}
else
{
return null;
}
}
public static implicit operator string(EnumType<T> dt)
{
return dt?.Value;
}
public static bool operator ==(EnumType<T> ct1, EnumType<T> ct2)
{
return (string)ct1 == (string)ct2;
}
public static bool operator !=(EnumType<T> ct1, EnumType<T> ct2)
{
return !(ct1 == ct2);
}
public override bool Equals(object obj)
{
try
{
return (string)obj == Value;
}
catch
{
return false;
}
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public static IEnumerable<T> All
=> typeof(T).GetProperties()
.Where(p => p.PropertyType == typeof(T))
.Select(x => (T)x.GetValue(null, null));
}
Я только тогда должен объявить это для моих перечислений:
public class TestEnum : EnumType<TestEnum>
{
private TestEnum(string value) : base(value)
{}
public static TestEnum Test1 { get { return new TestEnum("TEST1"); } }
public static TestEnum Test2 { get { return new TestEnum("TEST2"); } }
}