using System.ComponentModel;
public interface IKnowable
object Value { get; set; }
public struct Knowable<T> : IKnowable where T : Enum
private object _innerValue;
private set => _innerValue = value;
public bool IsKnown => Enum.IsDefined(typeof(T), InnerValue);
if (!IsKnown) throw new InvalidEnumArgumentException("Cannot convert inner value to known enum. Check that the enum IsKnown before trying to get the value.");
int => (T) Enum.ToObject(typeof(T), InnerValue),
string => (T) Enum.Parse(typeof(T), InnerValue.ToString()),
_ => throw new InvalidEnumArgumentException("Type of enum not known.")
private set => _innerValue = value.ToString();
set => InnerValue = value;
public static implicit operator Knowable<T>(string value)
return new Knowable<T> { InnerValue = value, };
public static implicit operator Knowable<T>(int value)
return new Knowable<T> { InnerValue = value, };
public static implicit operator Knowable<T>(T value)
return new Knowable<T> { Value = value, };
public static explicit operator T(Knowable<T> optional)
public class MyClassWithNormalEnum
public MyEnum MyEnum { get; set; }
public class MyClassWithKnowableEnum
public Knowable<MyEnum> MyEnum { get; set; }
public static void Main()
MyClassWithNormalEnum myClassWithNormalEnum = new MyClassWithNormalEnum();
Console.WriteLine(myClassWithNormalEnum.MyEnum);
MyClassWithKnowableEnum myClassWithKnowableEnum = new MyClassWithKnowableEnum();
Console.WriteLine(myClassWithKnowableEnum.MyEnum.InnerValue);