So I had this idea; what if I could decorate my Enum values with an attribute that cross-references a "default" value of another Enum that should be used when a variable of the current Enum type has this value?
The desired usage would look like:
public enum MyEnum
{
Value1,
Value2,
Value3,
}
public enum ControllingEnum
{
[LinkedValue(MyEnum.Value1)]
ControllingValue1,
[LinkedValue(MyEnum.Value2)]
ControllingValue2,
[LinkedValue(MyEnum.Value1)]
ControllingValue3,
[LinkedValue(MyEnum.Value3)]
ControllingValue4,
}
...
var relatedValue = ControllingEnum.ControllingValue4.GetLinkedValue<MyEnum>();
I came up with the following:
public class LinkedValueAttribute:Attribute
{
public LinkedValueAttribute(object value)
{
TypeOfValue = value.GetType();
Value = (Enum)value;
}
public Type TypeOfValue { get; private set; }
public Enum Value { get; private set; }
}
public static class AttributeHelper
{
public static T GetLinkedValue<T>(this Enum enumValue) where T:struct
{
if (!typeof(Enum).IsAssignableFrom(typeof(T)))
throw new InvalidOperationException("Generic type must be a System.Enum");
//Look for LinkedValueAttributes on the enum value
LinkedValueAttribute[] attr = enumValue.GetType().GetField(enumValue.ToString())
.GetCustomAttributes(typeof(LinkedValueAttribute), false)
.OfType<LinkedValueAttribute>()
.Where(a=>a.TypeOfValue == typeof(T))
.ToArray();
if (attr.Length > 0) // a DescriptionAttribute exists; use it
return (T)(object)attr[0].Value;
}
}
It does the job, but the boxing and unboxing are generally to be avoided. The question is, how?
GetLinkedValue
method can't compile - not all code paths return a value. – Jesse C. Slicer Aug 22 '12 at 19:35throw new InvalidOperationException("No cross-reference LinkedValueAttribute was found for the given value");
or evenreturn (T)(object)enumValue;
(which won't be all that useful). – Jesse C. Slicer Aug 22 '12 at 19:43