Usage of enumeration types

Source: Internet
Author: User
Tags assert constant expression integer numeric numeric value range reflection


C # Language Specification

14.3 The body of an enumeration member enumeration type declaration is used to define 0 or more enumeration members that are named constants of that enumeration type. Any two enumeration members cannot have the same name.

Enum-member-declarations: (enum member declaration:)
Enum-member-declaration (enumeration member declaration)
Enum-member-declarations, Enum-member-declaration (enumeration member declaration, enumeration member declaration)
Enum-member-declaration: (enum member declaration:)
attributesopt identifier (attribute optional identifier)
attributesopt identifier = constant-expression (attribute-selectable identifier = constant expression)
Each enumeration member has an associated constant value. The type of this value is the underlying type of the enumeration that contains it. The constant value of each enumeration member must be within the scope of the underlying type of the enumeration. Example

Enum Color:uint
{
Red =-1,
Green =-2,
Blue =-3
}
A compile-time error occurs because constant values-1,-2, and –3 are not in the range of the underlying integer uint.

Multiple enumeration members can share the same association value. Example

Enum Color
{
Red,
Green,
Blue,
Max = Blue
}
Displays an enumeration in which two enumeration members (Blue and Max) have the same associated value.

The associated value of an enumeration member or implicitly, or explicitly, is assigned a value. If the declaration of an enumeration member has a "constant expression" initializer, the value of the constant expression, which is implicitly converted to the underlying type of the enumeration, is the associated value of the enumeration member. If the declaration of an enumeration member does not have an initializer, its associated value is implicitly set according to the following rule:

If an enumeration member is the first enumeration member declared in an enumeration type, its association value is zero.
Otherwise, the associated value of an enumeration member is obtained by adding 1 to the associated value of the previous enumeration member (in text order). The added value must be within the range of the value that the underlying type can represent, otherwise a compile-time error occurs.
Example

Using System;
Enum Color
{
Red,
Green = 10,
Blue
}
Class Test
{
static void Main () {
Console.WriteLine (Stringfromcolor (color.red));
Console.WriteLine (Stringfromcolor (Color.green));
Console.WriteLine (Stringfromcolor (Color.Blue));
}
static string Stringfromcolor (Color c) {
Switch (c) {
Case Color.Red:
Return String.Format ("Red = {0}", (int) c);
Case Color.green:
Return String.Format ("Green = {0}", (int) c);
Case Color.Blue:
Return String.Format ("Blue = {0}", (int) c);
Default
Return "Invalid color";
}
}
}
Outputs enumeration member names and their associated values. The output is:

Red = 0
Green = 10
Blue = 11
The reasons are as follows:

The enumeration member Red is automatically assigned a value of 0 (because it does not have an initializer and is the first enumeration member).
Enum member Green is explicitly assigned a value of 10.
The enumeration member Blue is automatically assigned a value that is 1 larger than the member in front of the text.
The associated value of an enumeration member cannot directly or indirectly use the value of its own associated enumeration member. In addition to this cyclic restriction, enumeration member initializers are free to refer to other enum member initializers, regardless of the order in which they are located in the text position. Within an enumeration member initializer, the values of other enumeration members are always considered to belong to the underlying type, so it is not necessary to use a cast when referencing other enumeration members.

Example

Enum Circular
{
A = B,
B
}
A compile-time error occurs because the declarations of a and B are circular. A explicitly relies on B, and b implicitly relies on a.

Enumeration members are named and scoped in exactly the same way as fields in a class. The scope of an enumeration member is the body that contains its enumeration type. Within that scope, enumeration members can be referenced with their simple names. In all other code, the name of an enumeration member must be qualified with the name of its enumeration type. Enumeration members do not have any declarative accessibility, and if an enumeration type is accessible, all of the enumeration members it contains are accessible.



--------------------------------------------------------------------------------

Send feedback to Microsoft about this topic

©microsoft Corporation. All rights reserved.


Looking at this NUnit test code, we want to use the reflection mechanism to access the domain or property of an object's enumeration type at run time:



[Testfixture]
public class Paymentinfo
{
public enum Paymenttype
{
Cash, CreditCard, Check
}

Public Paymenttype Type;

public void Test ()
{
Paymentinfo payment = new Paymentinfo ();
Payment. Type = Paymenttype.cash;

System.Reflection.FieldInfo Enumfield = GetType (). GetField ("Type");

int paymentTypeInt32;

PaymentTypeInt32 = (int) enumfield.getvalue (payment);
Assert.AreEqual ((int) paymenttype.cash, paymentTypeInt32);

Enumfield.setvalue (payment, paymentTypeInt32);
Assert.AreEqual (Paymenttype.cash, payment. Type);
}
}



Actually, when you run the test, you are thrown an exception on this line of red: "Object type cannot be converted to target type." The reason for this is that the CLR's reflection mechanism does not allow implicit conversions between enumerated types and integer types. However, the C # compiler allows us to explicitly convert between the two by enforcing the syntax of the type conversion.



In this test, the way to pass is actually very simple: cast the underlined part to the enumeration type, such as: (Paymenttype) PaymentTypeInt32. The question is: How do you dynamically convert types at run time? For example, when I write elegantdal, I need to write a numeric value from the database to an enumerated field of the object to be returned, at which point I have only FieldInfo, Columnvalue and Resultobject, Writing Fieldinfo.setvalue (Resultobject, Columnvalue), however, would appear as the error mentioned earlier, But I have only one run-time type information (fieldinfo.fieldtype), and I can't write Fieldinfo.setvalue (Resultobject, Fieldinfo.fieldtype) columnvalue )......



We have to make this a special case, and our reinforcements are enum.toobject ()-Do you know a better way to solve the problem?


Enumeration types are another lightweight type of value in C #, and C # uses enumerations to express the set behavior of a specific set of values, such as the state of Windows Forms optional, the style of a button control, and so on. The following program Pseudocode shows a typical enumeration usage:
public enum Writingstyle
{
Classical,
Modern,
Elegant,
}
Class essay
{
public void Write (Writingstyle writingstyle)
{
Switch (Writingstyle)
{
Case Writingstyle.classical:
Classical style of writing
Break
Case Writingstyle.modern:
A modern style of writing
Break
Case Writingstyle.elegant:
Elegant style of writing
Break
Default
Throw (New System.ArgumentException ("Invalid writing Style"));
}
}
}
Note that the above enumerated symbols classical, modern, and elegant are separated by commas "," rather than semicolons ";". After the last enumeration value is elegant, you can omit the comma separator character.
As with structs, enumerations in C # do not allow their own inherited parent class System.Enum, as well as enumerations that cannot be inherited or abstract. The System.Enum class provides a number of useful functional operations for enumerated types. For example, we can get a string symbol representation of the enumeration value by GetName method. The following example shows some of the more common operations:

Using System;
public enum Writingstyle
{
Classical,
Modern,
Elegant,
}
Class Test
{
public static void Main ()
{
Writingstyle Dw=writingstyle.modern;

Console.WriteLine (Enum.getname (typeof (Writingstyle), DW);
Console.WriteLine (DW. ToString ());
Console.WriteLine (Enum.getunderlyingtype (typeof (Writingstyle)));
}
}
One of the last lines in the output of System.Int32, what's going on? We know that int is a shorthand for System.Int32, does our Writingstyle enum type have anything to do with the integer int type?
Yes, C # has a strict distinction between enumerations and integer values, such as we can't dw=1 similar assignments in the above code. But each enumeration value does have a numeric value of an integer type, and can be converted, except that the conversion must be expressed in a clear transition syntax. We know that in C # The integer types have byte, sbyte, short, ushort, int, uint, long, and ulong altogether eight species, so what is the integer type of C # 's enumeration value? It relates to the number of enumerated values that our enumeration types can hold. In fact, the C # enumeration type supports any of these eight integer types, which, depending on our needs, can be specified when declaring an enumeration type, such as "Public enum Writingstyle:byte", which specifies the integer type of its enumeration value as byte. The type can be obtained by the Enum.getunderlyingtype method described above. If not explicitly specified, C # uses the int type as the type of the enumerated value by default. Since the enumeration value is actually an integer value, what about its size? The reader can see the result by adding the following code to the main function above.
foreach (Object obj in Enum.getvalues (typeof (Writingstyle)))
{
Console.WriteLine (obj. ToString () + ":" + (int) obj);
}
The above code produces the following output:
classical:0
Modern:1
Elegant:2
As you can see, C # assigns an implied value to our enumeration value by default from 0. Of course, we can also specify values for enumerated values:
public enum Writingstyle
{
Classical=0,
MODERN=10,
ELEGANT=100,
}
We can even look like this if we have to make sure that we can compute their respective values at compile time.
public enum Writingstyle
{
Classical=0,
Modern=10+classical,
Elegant=10+modern,
}
Enumeration values also have a comparison, logic, arithmetic, and other actions like integers, and look at the following example:
Using System;
public enum Writingstyle
{
Classical=0,
Modern=10+classical,
Elegant=10+modern,
}
Class Test
{
public static void Main ()
{
Writingstyle Dw=writingstyle.modern;
Console.WriteLine (DW+10);
Console.WriteLine (dw+9);
}
}
When the calculated value equals the actual size of an enumeration value, the symbolic name of the enumeration value is displayed, otherwise the integer value is displayed.




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.