Monday, 7 October 2013

Enum in C#


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.
enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
Enumerators can use initializers to override the default values, as shown in the following example.
enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
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.
enum Days : byte {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.
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.
int x = (int)Days.Sun;
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;


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]Important note
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.
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.
For more information, see System.Enum.
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