I am trying to create an extension method that will return a List<string>
containing all the Description
attributes for only the set values of a given [Flags] Enum
.
For example, suppose I have the following enum declared in my C# code:
[Flags]
public enum Result
{
[Description("Value 1 with spaces")]
Value1 = 1,
[Description("Value 2 with spaces")]
Value2 = 2,
[Description("Value 3 with spaces")]
Value3 = 4,
[Description("Value 4 with spaces")]
Value4 = 8
}
And then have a variable set as:
Result y = Result.Value1 | Result.Value2 | Result.Value4;
So, the call I want to create would be:
List<string> descriptions = y.GetDescriptions();
and the final result would be:
descriptions = { "Value 1 with spaces", "Value 2 with spaces", "Value 4 with spaces" };
I have created an extension method for getting the single description attribute for an Enum that can not have multiple flags set that is along the following lines:
public static string GetDescription(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
System.Reflection.FieldInfo field = type.GetField(name);
if (field != null)
{
DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attr != null)
{
return attr.Description;
}
}
}
return null;
}
And I've found some answers online on how to get ALL the Description attributes for a given Enum type (such as here), but I'm having problems writing a generic extension method to return the list of descriptions for only the set attributes.
Any help would be really appreciated.
THANKS!!
HasFlag
is your friend. :-)
The extension method below uses the GetDescription extension method you've posted above, so ensure you have that. The following should then work:
public static List<string> GetDescriptionsAsText(this Enum yourEnum)
{
List<string> descriptions = new List<string>();
foreach (Enum enumValue in Enum.GetValues(yourEnum.GetType()))
{
if (yourEnum.HasFlag(enumValue))
{
descriptions.Add(enumValue.GetDescription());
}
}
return descriptions;
}
Note: HasFlag
allows you to compare a given Enum value against the flags defined. In your example, if you have
Result y = Result.Value1 | Result.Value2 | Result.Value4;
then
y.HasFlag(Result.Value1)
should be true, while
y.HasFlag(Result.Value3)
will be false.
See also: https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx
This is a compact solution using LINQ which also checks for null
in case not all of the values have attributes:
public static List<T> GetFlagEnumAttributes<T>(this Enum flagEnum) where T : Attribute
{
var type = flagEnum.GetType();
return Enum.GetValues(type)
.Cast<Enum>()
.Where(flagEnum.HasFlag)
.Select(e => type.GetMember(e.ToString()).First())
.Select(info => info.GetCustomAttribute<T>())
.Where(attribute => attribute != null)
.ToList();
}
You can iterate all values from enum and then filter them that isn't contained into your input value.
public static List<T> GetAttributesByFlags<T>(this Enum arg) where T: Attribute
{
var type = arg.GetType();
var result = new List<T>();
foreach (var item in Enum.GetValues(type))
{
var value = (Enum)item;
if (arg.HasFlag(value)) // it means that '(arg & value) == value'
{
var memInfo = type.GetMember(value.ToString())[0];
result.Add((T)memInfo.GetCustomAttribute(typeof(T), false));
}
}
return result;
}
And you get list of attributes that you want:
var arg = Result.Value1 | Result.Value4;
List<DescriptionAttribute> attributes = arg.GetAttributesByFlags<DescriptionAttribute>();
来源:https://stackoverflow.com/questions/45426266/get-description-attributes-from-a-flagged-enum