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
Rather than using Enum.GetValues
you will need to use reflection to find the static field list;
typeof(FamilyNameOptions)
.GetFields(BindingFlags.Static | BindingFlags.Public)
// For definition order, rather than value order;
.OrderBy(f => f.MetadataToken)
.Select(f => new {
Value = (FamilyNameOptions)f.GetValue(null),
Text = f.Name,
Enabled = f.GetCustomAttribute<DrawingListIsEnabledAttribute>()?.IsEnabled ?? false,
FamilyName = f.GetCustomAttribute<FamilyUserNameAttribute>()?.Name
})
Since none of that information will change at runtime, you might wish to create a helper type to cache the results.
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
..Select
statement gets the MemberInfo
objects describing the enum members (along with all custom attributes).Where
filters the results based on DrawingListIsEnabledAttribute
's IsEnabled
property.Select
grabs the names from the FamilyUserNameAttribute
's FamilyUserName
property (I presume that's what it's called - change it accordingly if not).