我有各种枚举用作下拉列表的来源,为了提供用户友好的描述,我为每个枚举添加了一个 Description
属性,然后执行以下操作:
var list = Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>()
.ToDictionary(k => k, v => v.GetAttributeOfType<DescriptionAttribute>().Description)
.ToList();
上面是重复的,因为我必须在很多地方使用它。我尝试添加一个扩展方法:
public static T GetAttributeOfType<T>(this Enum enumVal) where T : System.Attribute
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
return (attributes.Length > 0) ? (T)attributes[0] : null;
}
public static KeyValuePair<T, string> ToList<T>(this Enum source)
{
return Enum.GetValues(typeof(T))
.Cast<T>()
.ToDictionary(k => k, v => v.GetAttributeOfType<DescriptionAttribute>().Description)
.ToList();
}
但是,我得到一个异常(exception):
Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer' because it is not a delegate type
将其用作扩展的正确方法是什么(使用上述 2 种方法)?
最佳答案
What is the correct way to use it as an extension (using the above 2 methods)?
没有将其用作扩展 的正确方法。当您有一个值(实例)并且例如想要获取与该值相关的一些信息时,将使用扩展方法(类似于实例方法)。因此,如果您想获得单个 enum
的描述,扩展方法就有意义了。值(value)。
但是,在您的情况下,您需要的信息(enum
值/描述对的列表)未绑定(bind)到特定的 enum
值,但到 enum
类型。这意味着您只需要一个类似于 Enum.TryParse<TEnum>
的普通 static 通用方法.理想情况下,您会将通用参数限制为仅允许 enum
, 但这种类型的约束还不受支持 (还), 所以我们将使用 (类似于上面的系统方法) 只是 where TEnum : struct
并将添加运行时检查。
所以这是一个示例实现:
public static class EnumInfo
{
public static List<KeyValuePair<TEnum, string>> GetList<TEnum>()
where TEnum : struct
{
if (!typeof(TEnum).IsEnum) throw new InvalidOperationException();
return ((TEnum[])Enum.GetValues(typeof(TEnum)))
.ToDictionary(k => k, v => ((Enum)(object)v).GetAttributeOfType<DescriptionAttribute>().Description)
.ToList();
}
}
和用法:
public enum MyEnum
{
[Description("Foo")]
A,
[Description("Bar")]
B,
[Description("Baz")]
C,
}
var list = EnumInfo.GetList<MyEnum>();
关于c# - 枚举列为扩展名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36208281/