C#中如何为枚举类型添加描述方法

  • A+
所属分类:ASP.NET

C#中如何为枚举类型添加描述方法

在我们的日常开发中,我们会经常使用枚举类型。有时我们只需要显示枚举的值或者枚举值对应名称, 但是在某些场景下,我们可能需要将枚举值显示为不同的字符串。

  1. //例: 当前我们有如下枚举Level  
  2. public enum Level  
  3.     {  
  4.         //Bad  
  5.         B = -1,  
  6.   
  7.         //Normal  
  8.         N = 0,  
  9.   
  10.         //Good  
  11.         G = 1,  
  12.   
  13.         //Very Good   
  14.         VG = 2  
  15.     }  

这个枚举有4个可选值B, N, G, VG。 现在我们希望用Bad, Normal, Good, Very Good作为B, N, G, VG的显示值。

那我们会怎么做呢?通常我们最常想到的就是针对Level枚举类型编写一个扩展方法。

  1. public static class LevelEnumExtension  
  2.     {  
  3.         public static string ToDescription(this Level level)  
  4.         {  
  5.             switch (level)  
  6.             {  
  7.                 case Level.B:  
  8.                     return "Bad";  
  9.                 case Level.G:  
  10.                     return "Good";  
  11.                 case Level.N:  
  12.                     return "Normal";  
  13.                 case Level.VG:  
  14.                     return "Very Good";  
  15.                 default:  
  16.                     return "Normal";  
  17.             }  
  18.         }  
  19.     }  
    以上的代码在我们的项目中很常用。但是这里有2个潜在的问题:

  • 我们的项目中可能不止一种枚举类型,所以我们可能就需要为每一种类型都添加一个对应的扩展方法。
  • 枚举值和枚举的显示值的代码位置是分离的,如果你查找枚举值对应的显示值,你就要先去找到对应的枚举扩展方法。

那么如何改进这部分代码,从而消除上述2个问题呢,这时候我们就要引入.NET中的文本描述属性类DescriptionAttribute。

使用DescriptionAttribute重构代码

其实.NET中已经提供了一个文本描述属性类DescriptionAttribute, 这个属性类的构造函数可以接收一段文字描述。

  1. //下面我们使用DescriptionAttribute来改造Level枚举类型。  
  2. public enum Level  
  3.     {  
  4.         //Bad  
  5.         [Description("Bad")]  
  6.         B = -1,  
  7.   
  8.         //Normal  
  9.         [Description("Normal")]  
  10.         N = 0,  
  11.   
  12.         //Good  
  13.         [Description("Good")]  
  14.         G = 1,  
  15.   
  16.         //Very Good   
  17.         [Description("Very Good")]  
  18.         VG = 2  
  19.     }  

这样我们上面提到的第二个问题就解决了,现在Level枚举类型的枚举值和显示值就都封装在了一起。
那么第一个问题该怎么解决呢?
这里我们可以针对Enum类型添加扩展方法,并使用反射读取当前枚举值所对应的显示值

  1. public static class EnumExtension  
  2.     {  
  3.         public static string ToDescription(this Enum val)  
  4.         {  
  5.             var type = val.GetType();  
  6.   
  7.             var memberInfo = type.GetMember(val.ToString());  
  8.               
  9.             var attributes = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);  
  10.   
  11.             if (attributes == null || attributes.Length != 1)  
  12.             {  
  13.                 //如果没有定义描述,就把当前枚举值的对应名称返回  
  14.                 return val.ToString();  
  15.             }  
  16.   
  17.             return (attributes.Single() as DescriptionAttribute).Description;  
  18.         }  
  19.     }  

由于Enum类型是所有枚举类型的基类型,所以所有的枚举类型都可以使用这个扩展方法。

总结

本篇博文中,我们讲解了如果如何.NET内置的文本描述属性类DescriptionAttribute来生成枚举值对应的文本,它不仅可以减少重复代码,还可以让整个枚举类型的内聚性更高。

钰玺

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: