Detailed enumeration

Time:2020-2-26

Enumeration is the most interesting part of C ා and most developers only know a small part of it. Even most online tutorials only cover a part of enumeration. So, I will explain the knowledge of enumeration in detail through this article. I’ll start with what you all know, and then I’ll talk about what you don’t know or what you don’t know.

Zero. Basic knowledge

Enumeration is a kind of enumeration declared by developersValue type, which declares aNamed constant value。 Enumeration can make our code easy to read. Let’s take a look at two code segments:

//Code snippet 1
void Method(int country)
{
    switch (country)
    {
        case 0:
            // more code
            break;
        case 1:
            // more code
            break;
        case 2:
            // more code
            break;
        case 3:
            // more code
            break;
        default:
            // more code 
            break;
    }
}

//Code snippet 2
void Method(Country country)
{
    switch (country)
    {
        case Country.CN:
            // more code
            break;
        case Country.JP:
            // more code
            break;
        case Country.UK:
            // more code
            break;
        case Country.USA:
            // more code
            break;
        default:
            // more code 
            break;
    }
}

From the above two code snippets, we can see that there are obvious differences between them. In the first code, we hardly know what the case value means, but in the second code, we use enumeration, through which we can immediately know what we want to express. The readability of the code can also be improved by using enumeration value instead of Boolean value. For example, if we want to develop a program to turn on and off the control desk lamp, the code can be written in this way LightOperating(True) , but we can’t see what to do with this code. Now let’s change the code LightOperating(Light.On) 。 After modifying the code, it’s easy to see what you want to express.

  1. Enumeration definition and value
    There are two ways to define enumeration: normal way and custom way. Keywords needed no matter which way to use themenumTo identify that this type is an enumeration type, and the enumeration values are implemented as integer constants. Let’s take a look at how these two methods define enumeration. The normal way is often used by us, and it is also the default way. The code is as follows:

    enum Country
    {
        CN,
        UK,
        JP,
        USA
    }

    In the above code section, we define a country enumeration. The integer constant corresponding to the first enumeration value is0, the integer constant corresponding to the second enumeration value is1, and so on. The integer constants corresponding to the enumeration values are2and3。 But in some cases, we need to customize the integer constant corresponding to the enumeration value. At this time, we need to use the custom method. The custom method is also called enumeration value explicit assignment. Its method is as follows:

    enum Country
    {
        CN = 3,
        UK,
        JP = 70,
        USA = 67
    }

    In the code, we set the integer constant corresponding to the first enumeration value to 3, then the integer constant of the second enumeration value is not 1, but 4, because when the enumeration value does not display the assignment, the integer value corresponding to the previous enumeration value plus 1 will be used as the integer value corresponding to itself. Because the last two enumeration values are explicitly assigned, the corresponding integer value is the assigned value.
    Enumeration value is also very simple, onlyEnumeration name. Enumeration valueI.e Country.UK

    Tip: here are some suggestions:

    • The name of enumeration value should not contain enumeration name;
    • Enumeration names should appear in the singular (except for properties).
  2. Type of enumeration
    So far we have defined the underlying types used by enumeration typesintType, but enumeration can use not only int type, but alsocharAll base types other than type. We can use inheritance syntax to specify other types.

    enum Country:short
     {
         CN = 3,
         UK,
         JP = 70,
         USA = 67
     }

    In the above code, we explicitly defined the basic types used for enumeration asshort。 Although inheritance syntax is used here, no inheritance relationship is established. All enumeration base classes areSystem.Enum, these classes are sealed classes and cannot derive new members from existing enumeration types.
    For variables of enumeration type, the value is not limited to the value named in the declaration, so the value can be converted to the basic type, so it can be converted to enumeration type. The reason for this design is that it is possible to add new values to the enumeration without breaking the old version in the later API. But there is also a flaw in this. Enumeration allows unknown values to be assigned at run time, which we need to take into account in development. In addition, when adding new enumeration values to enumeration later, you should add them after all enumeration values, or display the value corresponding to the specified enumeration value, so as to avoid the change of the value corresponding to the enumeration value in the enumeration type due to adding new values.

    Tip: in development, we should try to use int as the basic type of enumeration, unless we consider smaller types due to performance problems or interoperability.

1、 Enumeration conversion

Enumeration conversion mainly involves enumeration and enumeration conversion, enumeration and number and string conversion.

  1. Conversion between enumerations
    First of all, I want to explain that direct conversion between different enumeration arrays is not supported in C ා, so if we want to realize the conversion between different enumeration arrays, we can use CLR’s loose assignment compatibility to convert. The two enumerations that need to be converted must have the same basic type. Again, let’s take an example to see how to implement it.

    static void Main(string[] args)
     {
         CountryAllName[] can = (CountryAllName[])(Array)new Country[4];
     }
    enum Country
     {
         CN,
         UK,
         JP,
         USA
     }
     enum CountryAllName
     {
         China,
         UnitedKingdom,
         Japan,
         UnitedStates
     }

    There may be unexpected errors or results when using this method, and the relevant development specifications do not say that this method works every time, so I do not recommend it unless in some extreme scenarios.

  2. Conversion between enumeration and string
    Enumerations converted to strings can be used directlyToString()Method, the enumeration value toString will directly output the string form of the enumeration value identifier, for exampleCountry.CN.ToString()The result is a stringCN。 Of course, you can also useEnum.GetNamesandEnum.GetNameMethod. Let me briefly explain the use of these two methods.

    • GetNames
      The getnames method needs to pass in an enumeration type, and the return value is an array of strings. For example, if you need to obtain the second country of country, you can writeEnum.GetNames(typeof(Country))[1], the result is UK.
    • GetName
      The getname method returns a string, which is the string form of the specified enumeration value to be obtained. Again, we get a second country,Enum.GetName(typeof(Country),1), the value returned is also UK.

String conversion to enumeration is also very simple. It also uses a static method of enum base classParse, for example, we can do this by converting JP to enumeration value of enumeration country(Country)Enum.Parse(typeof(Country),"JP")。 Here’s one thing to note,TryParseMethods only appear in. Net 4.0, so if you want to convert strings to enumerations under. Net 4.0, you need to take proper error handling to prevent strings from not existing in enumerations with enumerations in enumerations.

Tip: string to enumeration conversion is not localizable. If it has to be localized, it must be messages that are not visible to upper level users. Therefore, in the actual development, we should try to avoid the conversion between enumeration and string.

  1. Conversion between enumeration and number
    To convert enumeration to number, we can use strong conversion, such as(int)Country.CNThe return result is 0. There are two ways to convert numbers to enumerations. One is to use strong conversion, and the other is to use enum’s static distributionToObject

    • Strong turn
      It’s easier to make a strong turn,Country country = (Country)2
    • ToObject
      The toobject method needs to pass in enumeration types and numbers to convert, for exampleCountry country = (Country)Enum.ToObject(typeof(Country),2)
  2. Be careful
    String conversion to enumeration and number conversion to enumeration must first determine whether the value to be converted is included in the enumeration, and the method to be judged is very simple. Only the static method of enum needs to be calledIsDefinedOK. For example, I want to convert 0 and HK to enumeration. The code is as follows:

    Type type = typeof(Country);
     if(Enum.IsDefined(type,0))
     {
         Enum.ToObject(type, 0);
     }
     if(Enum.IsDefined(type,"HK"))
     {
         Enum.Parse(typeof(Country), "HK");
     }

    Only 0 in the above code will be successfully converted to the enumeration value CN, because the enumeration value of 0 is CN, and HK is not in the enumeration.

3、 Signs and attributes

In this section, we will talk about flags and attributes. Flags and attributes are less used in development, and most programmers don’t know much about them.

  1. sign
    In development, sometimes we want to combine enumeration to represent composite value. Then we need to define flag enumeration. The name of flag enumeration is complex and represents a set of flags. In general, we will use bitwise OR operator to link enumeration valuesHasFlagsMethod or by bit and operator to determine whether a particular bit exists. The classic enumeration of flags is located atSystem.IOIn namespaceFileAttributesFlag enumeration, which lists all attributes of a file, such as read-only, hidden, disk, etc. all enumeration values it contains can be combined with each other, for example, a file is both a hidden file and a read-only file. The way to define a flag enumeration is as follows:

    [Flags]
    enum WeekDays
     {
         Monday = 1,
         Tuesday = 2,
         Wednesday = 4,
         Thursday = 8,
         Friday = 16,
         Saturday = 32,
         Sunday = 64
     }

    In the above code, you will find a rule that the integer value corresponding to each enumeration value is the nth power of 2. Why. In the flag enumeration, it is required that the result of the combination of multiple enumeration values cannot be included in the flag enumeration, and based on the characteristics of bitwise operation, it is very convenient to use bit operators to calculate whether an enumeration value contains another enumeration value, which is quite useful in the permission system.

  2. attribute
    Properties can also be used for enumeration values. For example, if we need to print out the Chinese name of enumeration values, we can set it in the form of properties. First, we need to define a property:

    public class EnumChineseAttribute : Attribute
     {
         private string m_strDescription;
         public EnumChineseAttribute(string chineseName)
         {
             m_strDescription = chineseName;
         }
    
         public string Description
         {
             get { return m_strDescription; }
         }
     }
     enum Country
     {
         [enumchinese ("China")]
         CN,
         [enumchinese ("UK")]
         UK,
         [enumchinese ("Japan")]
         JP,
         [enumchinese ("us")]
         USA
     }
     static void Main(string[] args)
     {
         Country country = Country.CN;
         FieldInfo fieldInfo = country.GetType().GetField("CN");
         object[] attribArray = fieldInfo.GetCustomAttributes(false);
         EnumChineseAttribute attrib = (EnumChineseAttribute)attribArray[0];
         Console.WriteLine(attrib.Description);
         Console.Read();
     }

    Through the above code, we can get the Chinese name corresponding to CN. This code has not been further optimized, so it must be encapsulated and optimized in the actual project.

Four, summary

This article mainly explained the enumeration related knowledge, the content is a little trivial, but in the actual development is more practical. The points and regulations I mentioned in this article have been verified in the actual development, and you can use them directly.

This article is published by openwrite, a blog platform with one article and multiple posts!