从描述属性获取枚举

24 浏览
0 Comments

从描述属性获取枚举

我有一个通用的扩展方法,可以从枚举中获取Description属性:

enum Animal
{
    [Description("")]
    NotSet = 0,
    [Description("大熊猫")]
    GiantPanda = 1,
    [Description("小斑马")]
    LesserSpottedAnteater = 2
}
public static string GetDescription(this Enum value)
{            
    FieldInfo field = value.GetType().GetField(value.ToString());
    DescriptionAttribute attribute
            = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
                as DescriptionAttribute;
    return attribute == null ? value.ToString() : attribute.Description;
}

所以我可以这样做...

string myAnimal = Animal.GiantPanda.GetDescription(); // = "大熊猫"

现在,我正在尝试找出相反方向的等效函数,类似于...

Animal a = (Animal)Enum.GetValueFromDescription("大熊猫", typeof(Animal));

0
0 Comments

问题的原因是,如果在Web服务中使用该解决方案,将无法序列化Description属性。解决方法是使用DataContract特性和EnumMember特性来代替Description属性,并编写一个方法来获取枚举值的描述。

首先,在枚举定义中添加DataContract特性,并为每个枚举值添加EnumMember特性,用于指定其描述。然后,编写一个静态方法GetDescriptionFromEnumValue,该方法接受一个Enum类型的值作为参数,并通过反射获取该枚举值的EnumMemberAttribute特性,并返回其描述值。如果没有找到EnumMemberAttribute特性,则返回枚举值本身的字符串表示。

在使用GetDescriptionFromEnumValue方法之前,需要确保在代码中引入EnumMemberAttribute类所在的命名空间System.Runtime.Serialization。

这个解决方案非常适用于Web服务,因为它使用了与WCF(Windows Communication Foundation)兼容的EnumMember特性来提取枚举值的描述。

这个问题的解决方案是通过使用EnumMember特性和DataContract特性来代替Description属性,并编写一个方法来获取枚举值的描述。这个解决方案适用于Web服务,并且需要确保引入了System.Runtime.Serialization命名空间。

0
0 Comments

问题的出现原因是需要根据枚举类型的描述属性获取对应的枚举值,但是.NET Framework中没有直接提供这样的方法。为了解决这个问题,可以使用自定义的方法来实现。

解决方法是创建一个静态类`EnumEx`,其中包含一个泛型方法`GetValueFromDescription`。该方法使用反射获取指定枚举类型的所有字段,然后遍历每个字段。如果字段上存在`DescriptionAttribute`特性,并且该特性的描述与传入的参数相匹配,则返回该字段的值。如果字段上不存在`DescriptionAttribute`特性,则将字段的名称与传入的参数进行比较,如果相同则返回该字段的值。如果遍历完所有字段仍未找到匹配的值,则抛出`ArgumentException`异常。

可以通过以下方式调用该方法:

var panda = EnumEx.GetValueFromDescription("Giant Panda");

如果在方法签名中添加了`this`关键字,将其转换为扩展方法,则可以使用以下语法调用:

var x = "Giant Panda".GetValueFromDescription();

如果描述无效,可以使用以下方式判断:

var x = EnumEx.GetValueFromDescription("Dinosaur");

该调用会抛出异常,变量`x`不会包含任何值。

为了使代码正常工作,需要添加`using System.ComponentModel;`命名空间。

最后,还可以对比较进行不区分大小写的处理,可以使用`StringComparison.InvariantCultureIgnoreCase`参数来实现。

if (string.Equals(attribute.Description, description, StringComparison.InvariantCultureIgnoreCase))
    return (T)field.GetValue(null);

总结起来,以上是解决从描述属性获取枚举值的问题的方法,通过自定义的方法和反射来实现这一功能,使得开发者能够更方便地根据描述属性获取对应的枚举值。

0
0 Comments

问题的出现原因是希望能够通过描述属性获取枚举值,但是在C#中没有直接的方法可以实现这一点。为了解决这个问题,代码中提供了两个静态方法,一个是根据枚举值获取描述属性的值,另一个是根据描述属性的值获取枚举值。

首先是获取描述属性的值的方法,它使用了反射来获取枚举值对应的字段,并通过字段的GetCustomAttributes方法获取描述属性的值。如果找到了描述属性,则返回其值,否则返回枚举值本身。

接下来是根据描述属性的值获取枚举值的方法,它首先判断泛型类型是否为枚举类型,如果不是则抛出ArgumentException异常。然后使用反射获取所有字段,并通过LINQ查询找到描述属性的值与目标值相匹配的字段。如果找到了匹配的字段,则返回其枚举值,否则返回默认值。

代码中还提到了一个性能问题,即value.ToString()方法的调用比较昂贵,建议不要重复调用。此外,还提到了一个改进方法,即在方法签名中添加"where T : Enum"的约束条件,这样就不需要在运行时再次检查泛型类型是否为枚举类型。

然而,C#并不支持直接在泛型约束中使用"where T : Enum"的语法。但是可以使用第三方库Fody.ExtraConstraints来实现相同的效果,该库可以在编译时将约束条件转换为有效的代码。

总之,通过这段代码可以实现通过描述属性获取枚举值的功能,并提供了一些优化和改进方法来提高性能和代码可读性。

0