"Linked" Enum value attribute 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&lt;MyEnum&gt;();


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&lt;T&gt;(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&lt;LinkedValueAttribute&gt;()
            .Where(a=&gt;a.TypeOfValue == typeof(T))
            .ToArray();

        if (attr.Length &gt; 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?
I would personally write the attribute class as such:

[AttributeUsage(AttributeTargets.Field)]
public sealed class LinkedValueAttribute : Attribute
{
    private readonly Type typeOfValue;

    private readonly Enum value;

    public LinkedValueAttribute(object value)
    {
        this.typeOfValue = value.GetType();
        this.value = (Enum)value;
    }

    public Type TypeOfValue
    {
        get
        {
            return this.typeOfValue;
        }
    }

    public Enum Value
    {
        get
        {
            return this.value;
        }
    }
}


Reasons:

1: the AttributeUsage attribute limits it to going on fields, which, in this case, is the same as an enum member. Without it, the attribute can go onto anything anywhere, and while harmless from the point of the extension method, it is just a bit weird. Signify intent and don't let your users shoot themselves in the foot if you have the means.

2: sealed class. If you see no more functionality being added by subclasses in the future, seal it up. Compiler and JIT can do some optimizations knowing there are no descendants.

3: readonly fields instead of automatically implemented properties. First, signifies intent. Those fields will not be modified after the constructor assigns them. Don't let any future methods in that class noodle them unknowingly. Second, the compiler and JIT may do some optimizations based on knowing the fields will be unmolested after construction.

Now, in your extension method, since you already use LINQ, there's a couple more extensions you can use:

public static class AttributeHelper
{
    public static T GetLinkedValue&lt;T&gt;(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.
        var attributes = enumValue.GetType()
            .GetField(enumValue.ToString())
            .GetCustomAttributes(typeof(LinkedValueAttribute), false)
            .OfType&lt;LinkedValueAttribute&gt;()
            .Where(a =&gt; a.TypeOfValue == typeof(T));

        // A DescriptionAttribute exists; use it.
        if (attributes.Any())
        {
            return (T)(object)attributes.Single().Value;
        }

        throw new InvalidOperationException("No cross-reference LinkedValueAttribute was found for the given value");
    }
}


1: Removed .ToArray() since the LINQ extensions I use don't need an array to work on.

2: Changed attributes.Length &gt; 0 to attributes.Any(). This is primarily to signify intent. You want to know if there are any attributes returned, not particularly interested in the length of the array (that's no longer needed).

3: Changed attributes[0].Value to attributes.Single().Value. Because the default for AttributeUsage is Multiple = false and that's a good thing for the semantics of how it's used - we'll only get either zero or one back.

4: Added the exception throw I mentioned in my comment.

Now, as for the box/unbox... I'm still noodling on that one. I'll update this if/when I get something.

UPDATE I'm still not finding any way around the box/unbox issue. Reflection tricks and casting sorcery is still requiring the object bit.