Application Scenario: in a project, we are used to defining more stable classification standards as enumeration to ensure the legitimacy of values in the program and to make the code clearer. In some cases, you need to bind all enumeration values of an enumeration to the dropdownlist and other selection controls for your choice. In this case, you need to convert the enumerated values to the options of dropdownlist.
When I first met this requirement, I wrote a simple method as follows.
/// <Summary> /// urgency // </Summary> Public Enum eoa_emergencylevel {/// <summary> // flat /// </Summary> parts = 1, /// <summary> // urgent response // </Summary> urgent response = 2}
- Convert enumeration to arraylist
/// <Summary> /// convert enumeration to arraylist /// </Summary> /// <returns> </returns> Public static ilist enumtolist (type enumtype) {arraylist list = new arraylist (); foreach (int I in Enum. getvalues (enumtype) {listitem = new listitem (enum. getname (enumtype, I), I. tostring (); list. add (listitem) ;}return list ;}
/// <Summary> /// convert enumeration to a drop-down list /// </Summary> Public static void filldropdownlist (dropdownlist DDL, type enumtype) {DDL. items. clear (); DDL. datasource = enumtolist (enumtype); DDL. datavaluefield = "value"; DDL. datatextfield = "text"; DDL. databind ();}
Later, when my colleagues discussed the code, they were criticized for not using this Chinese enumeration name. At the same time, I also felt that this reflection method had a performance problem. However, since the impact is not big, I have been too lazy to handle it.
Recently I saw two blog posts (enumeration display and binding and an instance using the extension method: attachdataextensions), which were implemented using the extension method C #3.0 and were very beautiful, unfortunately, our project is based on. NET 2.0, not used. However, inspired by this, it took some time to use Attribute and Cache Technology to reconstruct the original code.
/// <Summary> /// display name of the enumeration /// </Summary> [Global: system. attributeusage (attributetargets. field, inherited = false, allowmultiple = false)] public sealed class enumshownameattribute: attribute {private string showname; /// <summary> /// display name /// </Summary> Public String showname {get {return this. showname ;}} /// <summary> /// display name for constructing enumeration /// </Summary> /// <Param name = "showname"> display name </param> Public enumshownameattribute (string showname) {This. showname = showname ;}}
/// <Summary> /// urgency // </Summary> Public Enum eoa_emergencylevel {/// <summary> // flat /// </Summary> [enumshowname ("parts")] common = 1, /// <summary> /// urgent // </Summary> [enumshowname ("urgent")] Emergency = 2}
/// <Summary> /// Enumeration Tool class /// </Summary> Public sealed class enumutil {Private Static dictionary <string, Dictionary <int, string >>_enumlist = new dictionary <string, Dictionary <int, string >> (); // enumeration cache pool /// <summary> /// bind the enumeration to listcontrol /// </Summary> /// <Param name = "listcontrol"> listcontrol </ param> // <Param name = "enumtype"> Enumeration type </param> Public static void filllistcontrol (listcontrol, type Enumtype) {listcontrol. items. clear (); listcontrol. datasource = enumtodictionary (enumtype); listcontrol. datavaluefield = "key"; listcontrol. datatextfield = "value"; listcontrol. databind () ;}/// <summary> /// convert the enumerated values to dictionary & lt; int, string & gt; // dictionary, key is the int value corresponding to the enumeration item; value is: if the enumshowname attribute is defined, it is used, otherwise, name /// </Summary> /// <Param name = "enumtype"> Enumeration type </param> /// <returns> </returns> Public Static dictionary <int, string> enumtodictionary (type enumtype) {string keyname = enumtype. fullname; If (! _ Enumlist. containskey (keyname) {dictionary <int, string> List = new dictionary <int, string> (); foreach (int I in Enum. getvalues (enumtype) {string name = enum. getname (enumtype, I); // obtain the display name string showname = string. empty; object [] ATTS = enumtype. getfield (name ). getcustomattributes (typeof (enumshownameattribute), false); If (ATTS. length> 0) showname = (enumshownameattribute) ATTS [0]). showname; List. Add (I, String. isnullorempty (showname )? Name: showname);} object syncobj = new object (); If (! _ Enumlist. containskey (keyname) {lock (syncobj) {If (! _ Enumlist. containskey (keyname) {_ enumlist. add (keyname, list) ;}}} return _ enumlist [keyname];} /// <summary> /// obtain the display name corresponding to the enumerated value /// </Summary> /// <Param name = "enumtype"> Enumeration type </param> /// <Param name = "intvalue"> int value corresponding to the enumerated item </param> /// <returns> </returns> Public static string getenumshowname (type enumtype, int intvalue) {return enumtodictionary (enumtype) [intvalue] ;}}
To be more lazy, you can also save the custom enumshownameattribute and simply use system. componentmodel. descriptionattribute.
[Appendix] basic Enum knowledge:
- C # Enum Enumeration
- Use of flags enumeration in. net
- FAQ on enumeration [C #, Il, Bcl]