'Perform LINQ operations on an Enum based on Attributes

I'm trying to query against my Enum based on an attribute on each enum option.

I know how to get the list. That is pretty simple via this code:

            var list = Enum.GetValues(typeof(FamilyNameOptions))
                    .Cast<FamilyNameOptions>()
                    .Select(v => v.ToString())
                    .ToList();

If this is my Enum setup, how can I query against the attribute DrawingListIsEnabled where the value is TRUE

    public enum FamilyNameOptions
    {
        [DrawingListIsEnabled(true)]
        [FamilyUserName("FamilyName1")]
        FamilyName1= 0,

        [DrawingListIsEnabled(false)]
        [FamilyUserName("FamilyName2")]
        FamilyName2= 1,
    }


    /// <summary>
    /// DrawingListIsEnabledAttribute
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.All)]
    public class DrawingListIsEnabledAttribute : Attribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingListIsEnabledAttribute"/> class.
        /// </summary>
        /// <param name="isEnabled">if set to <c>true</c> [is enabled].</param>
        public DrawingListIsEnabledAttribute(bool isEnabled)
        {
            this.IsEnabled = isEnabled;
        }

        /// <summary>
        /// Gets a value indicating whether this instance is enabled.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is enabled; otherwise, <c>false</c>.
        /// </value>
        public bool IsEnabled { get; private set; }
    }

The expected result would be a list of 1:

FamilyName1



Solution 1:[1]

Here's a simple LINQ query to accomplish this task:

var items = Enum.GetValues<FamilyNameOptions>()
                .Select(item => item.GetType().GetMember(item.ToString()).FirstOrDefault())
                .Where(memberInfo => memberInfo?.GetCustomAttribute<DrawingListIsEnabledAttribute>().IsEnabled ?? false)
                .Select(enabledMemberInfo => enabledMemberInfo.GetCustomAttribute<FamilyUserNameAttribute>().FamilyUserName);

Note, you don't need your original list. Also, I'm using the generic version of Enum.GetValues<TEnum>, which eliminates the need for Cast in your version.

I kept my LINQ names long in effort to be self-documenting; feel free to go with the typical shorter names. The code works as follows:

  • Enum.GetValues<FamilyNameOptions> returns a strongly-typed list of members of enum FamilyNameOptions.
  • first .Select statement gets the MemberInfo objects describing the enum members (along with all custom attributes)
  • next, .Where filters the results based on DrawingListIsEnabledAttribute's IsEnabled property
  • finally, the last .Select grabs the names from the FamilyUserNameAttribute's FamilyUserName property (I presume that's what it's called - change it accordingly if not).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1