从标记的枚举中获取描述属性
Get Description Attributes From a Flagged Enum
我正在尝试创建一个扩展方法,它将 return 一个 List<string>
只包含给定 [Flags] Enum
的设置值的所有 Description
属性。
例如,假设我在 C# 代码中声明了以下枚举:
[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
}
然后将变量设置为:
Result y = Result.Value1 | Result.Value2 | Result.Value4;
所以,我想创建的调用是:
List<string> descriptions = y.GetDescriptions();
最终结果为:
descriptions = { "Value 1 with spaces", "Value 2 with spaces", "Value 4 with spaces" };
我创建了一个扩展方法,用于为不能设置多个标志的枚举获取单个描述属性,如下所示:
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;
}
而且我在网上找到了一些关于如何获取给定枚举类型(例如 here)的所有描述属性的答案,但是我在为 [= 编写通用扩展方法时遇到了问题41=] 描述列表 仅针对设置的属性。
任何帮助将不胜感激。
谢谢!!
HasFlag
是你的朋友。 :-)
下面的扩展方法使用了您在上面发布的 GetDescription 扩展方法,因此请确保您拥有该扩展方法。然后应该可以使用以下内容:
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;
}
注意:HasFlag
允许您将给定的枚举值与定义的标志进行比较。在你的例子中,如果你有
Result y = Result.Value1 | Result.Value2 | Result.Value4;
然后
y.HasFlag(Result.Value1)
应该是真的,而
y.HasFlag(Result.Value3)
将为假。
另请参阅:https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx
您可以迭代枚举中的所有值,然后过滤掉不包含在您的输入值中的值。
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;
}
你会得到你想要的属性列表:
var arg = Result.Value1 | Result.Value4;
List<DescriptionAttribute> attributes = arg.GetAttributesByFlags<DescriptionAttribute>();
这是一个使用 LINQ 的紧凑型解决方案,它还会检查 null
以防并非所有值都具有属性:
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();
}
我正在尝试创建一个扩展方法,它将 return 一个 List<string>
只包含给定 [Flags] Enum
的设置值的所有 Description
属性。
例如,假设我在 C# 代码中声明了以下枚举:
[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
}
然后将变量设置为:
Result y = Result.Value1 | Result.Value2 | Result.Value4;
所以,我想创建的调用是:
List<string> descriptions = y.GetDescriptions();
最终结果为:
descriptions = { "Value 1 with spaces", "Value 2 with spaces", "Value 4 with spaces" };
我创建了一个扩展方法,用于为不能设置多个标志的枚举获取单个描述属性,如下所示:
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;
}
而且我在网上找到了一些关于如何获取给定枚举类型(例如 here)的所有描述属性的答案,但是我在为 [= 编写通用扩展方法时遇到了问题41=] 描述列表 仅针对设置的属性。
任何帮助将不胜感激。
谢谢!!
HasFlag
是你的朋友。 :-)
下面的扩展方法使用了您在上面发布的 GetDescription 扩展方法,因此请确保您拥有该扩展方法。然后应该可以使用以下内容:
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;
}
注意:HasFlag
允许您将给定的枚举值与定义的标志进行比较。在你的例子中,如果你有
Result y = Result.Value1 | Result.Value2 | Result.Value4;
然后
y.HasFlag(Result.Value1)
应该是真的,而
y.HasFlag(Result.Value3)
将为假。
另请参阅:https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx
您可以迭代枚举中的所有值,然后过滤掉不包含在您的输入值中的值。
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;
}
你会得到你想要的属性列表:
var arg = Result.Value1 | Result.Value4;
List<DescriptionAttribute> attributes = arg.GetAttributesByFlags<DescriptionAttribute>();
这是一个使用 LINQ 的紧凑型解决方案,它还会检查 null
以防并非所有值都具有属性:
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();
}