I have seen lots of people,who are confused about enum,so lets read about enum and understand Use.
What is Enum?
The enum keyword is used to declare an enumeration, a
distinct type that consists of a set of named constants called the enumerator
list.
Usually it is best to
define an enum directly within a namespace so that all classes in the namespace
can access it with equal convenience. However, an enum can also be nested
within a class or struct.
By default, the first
enumerator has the value 0, and the value of each successive enumerator is
increased by 1. For example, in the following enumeration, Sat is 0, Sun is 1, Mon is 2, and so forth.
Enumerators can use
initializers to override the default values, as shown in the following example.
In this enumeration, the
sequence of elements is forced to start from 1 instead of 0. However, including a
constant that has the value of 0 is recommended.
Every enumeration type
has an underlying type, which can be any integral type except char. The default underlying type of enumeration elements is int. To declare an enum of another integral type, such as byte, use a colon after the identifier followed by the type, as shown
in the following example.
A variable of type Days can be assigned any value in the range of the
underlying type; the values are not limited to the named constants.
The default value of an enum E is the value produced by the expression (E) 0.
Note : An
enumerator cannot contain white space in its name.
|
The underlying type
specifies how much storage is allocated for each enumerator. However, an
explicit cast is necessary to convert from enum type to an integral type. For example, the following statement
assigns the enumerator Sun to
a variable of the type int by using a cast to convert from enum to int.
When you apply System.FlagsAttribute to an enumeration that contains elements that
can be combined with a bitwise OR operation,
the attribute affects the behavior of the enum when it is used with some tools. You can notice these changes when
you use tools such as the Console class methods and the Expression Evaluator. (See the third
example.)
Just as with any
constant, all references to the individual values of an enum are converted to
numeric literals at compile time. This can create potential versioning issues
as described in Constants (C# Programming Guide).
Assigning additional
values to new versions of enums, or changing the values of the enum members in
a new version, can cause problems for dependent source code. Enum values often
are used in switch statements. If additional elements have been added to the enum type, the default section of the switch
statement can be selected unexpectedly.
If other developers use
your code, you should provide guidelines about how their code should react if
new elements are added to any enum types.
In the following
example, an enumeration, Days, is declared. Two
enumerators are explicitly converted to integer and assigned to integer
variables.
public class EnumTest
{ enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
static void Main()
{ int x = (int)Days.Sun;
int y = (int)Days.Fri;
Console.WriteLine("Sun = {0}", x);
Console.WriteLine("Fri = {0}", y);
}}/* Output: Sun = 0 Fri = 5*/
public class EnumTest2
{
enum Range : long { Max = 2147483648L, Min = 255L };
static void Main()
{
long x = (long)Range.Max;
long y = (long)Range.Min;
Console.WriteLine("Max = {0}", x);
Console.WriteLine("Min = {0}", y);
}
}
/* Output:
Max = 2147483648
Min = 255
*/
// Add the attribute Flags or FlagsAttribute.
[Flags]
public enum CarOptions
{
// The flag for SunRoof is 0001.
SunRoof = 0x01,
// The flag for Spoiler is 0010.
Spoiler = 0x02,
// The flag for FogLights is 0100.
FogLights = 0x04,
// The flag for TintedWindows is 1000.
TintedWindows = 0x08,
}
class FlagTest
{
static void Main()
{
// The bitwise OR of 0001 and 0100 is 0101.
CarOptions options = CarOptions.SunRoof | CarOptions.FogLights;
// Because the Flags attribute is specified, Console.WriteLine displays
// the name of each enum element that corresponds to a flag that has
// the value 1 in variable options.
Console.WriteLine(options);
// The integer value of 0101 is 5.
Console.WriteLine((int)options);
}
}
/* Output:
SunRoof, FogLights
5
*/
Comments
Enumeration Types (C# Programming Guide)
enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
enum Months : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
Days meetingDay = Days.Monday;
//...
meetingDay = Days.Friday;
enum MachineState
{
PowerOff = 0,
Running = 5,
Sleeping = 10,
Hibernating = Sleeping + 5
}
[Flags]
enum Days2
{
None = 0x0,
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
class MyClass
{
Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}
// Initialize with two flags using bitwise OR.
meetingDays = Days2.Tuesday | Days2.Thursday;
// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Tuesday, Thursday, Friday
// Remove a flag using bitwise XOR.
meetingDays = meetingDays ^ Days2.Tuesday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Thursday, Friday
// Test value of flags using bitwise AND.
bool test = (meetingDays & Days2.Thursday) == Days2.Thursday;
Console.WriteLine("Thursday {0} a meeting day.", test == true ? "is" : "is not");
// Output: Thursday is a meeting day.
string s = Enum.GetName(typeof(Days), 4);
Console.WriteLine(s);
Console.WriteLine("The values of the Days Enum are:");
foreach (int i in Enum.GetValues(typeof(Days)))
Console.WriteLine(i);
Console.WriteLine("The names of the Days Enum are:");
foreach (string str in Enum.GetNames(typeof(Days)))
Console.WriteLine(str);
public static class BadFurnishings
{
public static int Table = 1;
public static int Chair = 2;
public static int Lamp = 3;
}
public enum GoodFurnishings
{
Table,
Chair,
Lamp
}
public enum Furniture
{
Desk,
Chair,
Lamp,
Rug,
LastValue // The sentinel value.
}
public enum PurchaseTypes
{
SalePrice,
RegularPrice,
Book,
CompactDisk
}
public float FindPriceForItem(string title, PurchaseTypes purchase)
public enum ItemType
{
Book,
CompactDisk
}
public enum PriceType
{
SalePrice,
RegularPrice,
}
public float FindPriceForItem(string title, ItemType name, PriceType price)
NOTE - Do not use the value zero in a flags enumeration to indicate any other state. There is no way to check for a zero value flag being explicitly set, as opposed to no flags being set.
In the following example, the base-type option is used to declare an enum whose members are of type long. Notice that even though the underlying type of the enumeration is long, the enumeration members still must be explicitly converted to type long by using a cast.
public class EnumTest2
{
enum Range : long { Max = 2147483648L, Min = 255L };
static void Main()
{
long x = (long)Range.Max;
long y = (long)Range.Min;
Console.WriteLine("Max = {0}", x);
Console.WriteLine("Min = {0}", y);
}
}
/* Output:
Max = 2147483648
Min = 255
*/
// Add the attribute Flags or FlagsAttribute.
[Flags]
public enum CarOptions
{
// The flag for SunRoof is 0001.
SunRoof = 0x01,
// The flag for Spoiler is 0010.
Spoiler = 0x02,
// The flag for FogLights is 0100.
FogLights = 0x04,
// The flag for TintedWindows is 1000.
TintedWindows = 0x08,
}
class FlagTest
{
static void Main()
{
// The bitwise OR of 0001 and 0100 is 0101.
CarOptions options = CarOptions.SunRoof | CarOptions.FogLights;
// Because the Flags attribute is specified, Console.WriteLine displays
// the name of each enum element that corresponds to a flag that has
// the value 1 in variable options.
Console.WriteLine(options);
// The integer value of 0101 is 5.
Console.WriteLine((int)options);
}
}
/* Output:
SunRoof, FogLights
5
*/
Comments
Enumeration Types (C# Programming Guide)
enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
enum Months : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
Days meetingDay = Days.Monday;
//...
meetingDay = Days.Friday;
NOTE-It is possible to assign any arbitrary integer value to meetingDay. For example, this line of code does not produce an error: meetingDay = (Days) 42. However, you should not do this because the implicit expectation is that an enum variable will only hold one of the values defined by the enum. To assign an arbitrary value to a variable of an enumeration type is to introduce a high risk for errors.
enum MachineState
{
PowerOff = 0,
Running = 5,
Sleeping = 10,
Hibernating = Sleeping + 5
}
[Flags]
enum Days2
{
None = 0x0,
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
class MyClass
{
Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}
// Initialize with two flags using bitwise OR.
meetingDays = Days2.Tuesday | Days2.Thursday;
// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Tuesday, Thursday, Friday
// Remove a flag using bitwise XOR.
meetingDays = meetingDays ^ Days2.Tuesday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Thursday, Friday
// Test value of flags using bitwise AND.
bool test = (meetingDays & Days2.Thursday) == Days2.Thursday;
Console.WriteLine("Thursday {0} a meeting day.", test == true ? "is" : "is not");
// Output: Thursday is a meeting day.
string s = Enum.GetName(typeof(Days), 4);
Console.WriteLine(s);
Console.WriteLine("The values of the Days Enum are:");
foreach (int i in Enum.GetValues(typeof(Days)))
Console.WriteLine(i);
Console.WriteLine("The names of the Days Enum are:");
foreach (string str in Enum.GetNames(typeof(Days)))
Console.WriteLine(str);
public static class BadFurnishings
{
public static int Table = 1;
public static int Chair = 2;
public static int Lamp = 3;
}
public enum GoodFurnishings
{
Table,
Chair,
Lamp
}
public enum Furniture
{
Desk,
Chair,
Lamp,
Rug,
LastValue // The sentinel value.
}
Note-If you do not use powers of two or combinations of powers of two, bitwise operations will not work as expected. [Flags] ![]() |
{
SalePrice,
RegularPrice,
Book,
CompactDisk
}
public float FindPriceForItem(string title, PurchaseTypes purchase)
public enum ItemType
{
Book,
CompactDisk
}
public enum PriceType
{
SalePrice,
RegularPrice,
}
public float FindPriceForItem(string title, ItemType name, PriceType price)
NOTE - Do not use the value zero in a flags enumeration to indicate any other state. There is no way to check for a zero value flag being explicitly set, as opposed to no flags being set.
In the following example, the base-type option is used to declare an enum whose members are of type long. Notice that even though the underlying type of the enumeration is long, the enumeration members still must be explicitly converted to type long by using a cast.
The following code example
illustrates the use and effect of the System.FlagsAttribute attribute
on an enum declaration.
If you remove Flags, the example displays the following values:
5
5
Visual Studio 2010
An enumeration type (also named an enumeration or an enum)
provides an efficient way to define a set of named integral constants that may
be assigned to a variable. For example, assume that you have to define a
variable whose value will represent a day of the week. There are only seven
meaningful values which that variable will ever store. To define those values,
you can use an enumeration type, which is declared by using the enum keyword.
By default the underlying type of each element in the enum is int. You
can specify another integral numeric type by using a colon, as shown in the
previous example. For a full list of possible types, see enum
(C# Reference).
The following are advantages of using an enum instead of a numeric
type:
·
You clearly specify for client code which values are valid for the
variable.
·
In Visual Studio, IntelliSense lists the defined values.
When you do not specify values for the elements in the enumerator
list, the values are automatically incremented by 1. In the previous example, Days.Sunday has a value of 0, Days.Monday has a value of 1, and so on. When you
create a new Days object, it will have a default value
of Days.Sunday (0) if you do not explicitly assign it
a value. When you create an enum, select the most logical default value and
give it a value of zero. That will cause all enums to have that default value
if they are not explicitly assigned a value when they are created.
If the variable meetingDay is
of type Days,
then (without an explicit cast) you can only assign it one of the values
defined by Days.
And if the meeting day changes, you can assign a new value from Days to meetingDay:
You can assign any values to the elements in the enumerator list
of an enumeration type, and you can also use computed values:
You can use an enumeration type to define bit flags, which enables
an instance of the enumeration type to store any combination of the values that
are defined in the enumerator list. (Of course, some combinations may not be
meaningful or allowed in your program code.)
You create a bit flags enum by applying the System.FlagsAttribute attribute and defining the values
appropriately so that AND, OR, NOT and XOR bitwise operations can be performed on
them. In a bit flags enum, include a named constant with a value of zero that
means "no flags are set." Do not give a flag a value of zero if it
does not mean "no flags are set".
In the following example, another version of the Days enum, which is named Days2, is
defined. Days2 has the Flags attribute and each value is assigned
the next greater power of 2. This enables you to create a Days2 variable whose value is Days2.Tuesday and Days2.Thursday.
To set a flag on an enum, use the bitwise OR operator
as shown in the following example:
To determine whether a specific flag is set, use a bitwise AND operation,
as shown in the following example:
For more information about what to consider when you define
enumeration types with the System.FlagsAttribute attribute,
see System.Enum.
All enums are instances of the System.Enum type.
You cannot derive new classes from System.Enum, but you can use its methods to discover information about and
manipulate values in an enum instance.
You can also create a new method for an enum by using an extension
method. For more information, see How
to: Create a New Method for an Enumeration (C# Programming Guide).
Enumeration
Design
.NET Framework 4
Enumerations provide sets of constant values that are useful for
strongly typing members and improving readability of code. Enumerations are
either simple or flags. Simple enumerations contain values that are not
combined or used in bitwise comparisons. Flags enumerations are intended to be
combined using bitwise OR operations. Combinations of flags enumeration values
are examined using bitwise AND operations.
The following guidelines describe the best practices for
enumeration design.
Do use an enumeration to strongly type parameters, properties, and
return values that represent sets of values.
Do favor using an enumeration instead of static constants.
The following code example demonstrates the incorrect design.
The following code example demonstrates the enumeration that
should be used in place of the static constants.
Do not use an enumeration for open sets such as the operating
system version.
Adding values to an enumeration that has already shipped can break
existing code. There are times when this is acceptable, but you should not design
an enumeration where this is likely to be the case.
Do not define reserved enumeration values that are intended for
future use.
In some situations you might decide that adding values to the
shipped enumeration is worth the risk of possibly breaking existing code. You
can also define a new enumeration and members that work with its values.
Avoid publicly exposing enumerations with only one value.
Do not include sentinel values in enumerations.
Sentinel values are used to identify the boundaries of values in
the enumeration. Typically a sentinel value is used in range checks and is not
a valid data value. The following code example defines an enumeration with a
sentinel value.
Do provide a value of zero on simple enumerations.
If possible, name this value None. If None is not
appropriate, assign the value zero to the most commonly used value (the
default).
Consider using System.Int32 (the default data type in most
programming languages) as the underlying data type of an enumeration unless any
of the following is true:
·
The enumeration is a flags enumeration, and you have more than 32
flags or expect to have more in the future.
·
The underlying type needs to be different than Int32 for easier interoperability with unmanaged
code expecting different size enumerations.
·
A smaller underlying type would result in substantial savings in
space. If you expect an enumeration to be used mainly as an argument for flow
of control, the size makes little difference. The size savings might be
significant if:
·
You expect the enumeration to be used as a field in a very
frequently instantiated structure or class.
·
You expect users to create large arrays or collections of
enumeration instances.
·
You expect a large number of instances of the enumeration to be
serialized.
Do name flags enumerations with plural nouns or noun phrases.
Simple enumerations should be named with singular nouns or noun phrases.
Do not extend System.Enum directly.
Some compilers do not allow you to extend Enum unless you do it indirectly using the
language-specific key word for generating enumerations.
Designing
Flags Enumerations
.NET Framework 4
Flags enumerations are
used for masking bit fields and doing bitwise comparisons. They are the correct
design to use when multiple enumeration values can be specified at the same
time. For example, you can combine any of the GenericUriParserOptions enumeration values to configure a generic
Uniform Resource Identifier (URI) parser.
Do apply the
System.FlagsAttribute to flags enumerations. Do not apply this attribute to
simple enumerations.
Do use powers of two for
a flags enumeration's values so they can be freely combined using the bitwise
OR operation.
Consider providing
special enumeration values for commonly used combinations of flags.
Combining flags
enumeration values is an intermediate skill that should not be required for
developers implementing common scenarios. For example, theFileShare enumeration contains the ReadWrite value to specify that a shared file can be
opened for reading or writing. This shows developers that they can open a
shared file for reading or writing, and eliminates the need for them to learn
how to specify a combination of enumeration values as a single value.
Avoid creating flags
enumerations when certain combinations of values are invalid.
This problem typically
indicates that the meaning of the enumeration is not sufficiently precise.
Consider dividing the enumeration into two or more enumerations, each having a
more precise set of values. For example, consider the following poorly defined
enumeration.
The designer intends this enumeration to be used with the
following method.
When calling this method, the purchase parameter
specifies exactly one of the SalePrice or RegularPrice values and exactly one of the Book or CompactDisk values.
Developers would not be able to determine this requirement without consulting
the documentation or experimenting with the method. A better approach is to
separate the two kinds of information, placing each in its own enumeration, as
shown in the following code example.
The method signature would now change to reflect this redesign, as
shown in the following code example.
Avoid setting a flags enumeration value to zero, unless the value
is used to indicate that all flags are cleared. Such a value should be named
appropriately as described in the next guideline.
Note that this guideline
is only for flags enumerations. Simple enumerations can and should use the zero
value.
Do name the zero value of flags enumerations None. For a flags
enumeration, the value must always mean all flags are cleared.
Adding
Values to Enumerations
.NET Framework 4
The following guideline discusses introducing a potentially
breaking change for users of your libraries. If you add values to a previously
shipped enumeration, existing application code might not be robust enough to
gracefully handle the new values.
Consider adding values to enumerations despite a small
compatibility risk.
This guideline is relevant when you expect to be shipping more than one
version of your library. To minimize the code that breaks due to adding values
to an existing enumeration, you can implement new members that return the full
set of values and mark the existing members (that return the original set of
values) using the ObsoleteAttribute attribute. If breaking changes are not acceptable, you can define a new
enumeration and the associated members that work with it, and mark the existing
members and enumeration as obsolete.
No comments:
Post a Comment