Pages

Sunday, 28 June 2015

Enumeration

Enumerations

An enumeration, or enum, is a programmer-defined type, such as a class or a struct.
  • Like structs, enums are value types and therefore store their data directly, rather than separately, with a reference and data.
  • Enums have only one type of member: named constants with integer values.
The following code shows an example of the declaration of a new enum type called TrafficLight, which contains three members. Notice that the list of member declarations is a comma-separated list; there are no semicolons in an enum declaration.
enum TrafficLight
{
 Green, //Comma separated—no semicolons
 Yellow, //Comma separated—no semicolons
 Red
}

Every enum type has an underlying integer type, which by default is int.
  • Each enum member is assigned a constant value of the underlying type.
  • By default, the compiler assigns 0 to the first member and assigns each subsequent member the value one more than the previous member.
See following code for better understanding:
 static void Main(string[] args)
{
 TrafficLight t1 = TrafficLight.Green;
 TrafficLight t2 = TrafficLight.Yellow;
 TrafficLight t3 = TrafficLight.Red;
 Console.WriteLine(t1 + " = " + (int)t1);       //casting to integer
 Console.WriteLine(t2 + " = " + (int)t2);       //casting to integer
 Console.WriteLine(t3 + " = " + (int)t3);       //casting to integer
}
This code produces the following output:
Green = 0
Yellow = 1
Red = 2

Setting the Underlying Type and Explicit Values

You can use an integer type other than int by placing a colon and the type name after the enum name. The type can be any integer type. All the member constants are of the enum’s underlying type.
enum [Enum Name] : [Type]
{ 
 ...  
}

The values of the member constants can be any values of the underlying type. To explicitly set the value of a member, use an initializer after its name in the enum declaration. There can be duplicate values, although not duplicate names, as shown here:
class Program
{
 enum TrafficLight : ushort
 {
  Green=2, //Comma separated—no semicolons
  Yellow=7, //Comma separated—no semicolons
  Red=14,
  Unknown = 14
 }
 static void Main(string[] args)
 {
  TrafficLight t1 = TrafficLight.Green;
  TrafficLight t2 = TrafficLight.Yellow;
  TrafficLight t3 = TrafficLight.Red;
  TrafficLight t4 = TrafficLight.Unknown;
  Console.WriteLine(t1 + " = " + (int)t1);       //casting to integer
  Console.WriteLine(t2 + " = " + (int)t2);       //casting to integer
  Console.WriteLine(t3 + " = " + (int)t3);       //casting to integer
  Console.WriteLine(t4 + " = " + (int)t4);       //casting to integer
 }
}

The Output will be:
Green = 2
Yellow = 7
Red = 14
Red = 14

Implicit Member Numbering

You can explicitly assign the values for any of the member constants. If you don’t initialize a member constant, the compiler implicitly assigns it a value.
See Following Example:
enum FaceCards
{
 Jack = 11,    // 11 - Explicitly set
 Queen,      // 12 - One more than the previous one
 King,      // 13 - One more than the previous one
 Ace,      // 14 - One more than the previous one
 NumberOfFaceCards = 4,  // 4 - Explicitly set
 SomeOtherValue,   // 5 - One more than the previous one
 HighestFaceCard = Ace  // 14 - Ace is defined above
}

Bit Flags

Programmers have long used the different bits in a single word as a compact way of representing a set of on/off flags. The general steps are the following:
  1. Determine how many bit flags you need and choose an unsigned integer type with enough bits to hold them.
  2. Determine what each bit position represents and give it a name. Declare an enum of the chosen integer type, with each member represented by a bit position.
  3. Use the bitwise OR operator to set the appropriate bits in a word holding the bit flags.
  4. You can then check whether a particular bit flag is set by using either the HasFlag method or the bitwise AND operator.
For example, the following code shows the enum declaration representing the options for a card deck in a card game.
class Program
{
 [Flags]
 enum CardDeckSettings : uint
 {
  SingleDeck = 0x01, // bit 0
  LargePictures = 0x02, // bit 1
  FancyNumbers = 0x04, // bit 2
  Animation = 0x08 // bit 3
 }

 static bool UseSingleDeck = false, UseBigPics = false, UseFancyNumbers = false,
   UseAnimation = false, UseAnimationAndFancyNumbers = false;
 
 static void SetOptions(CardDeckSettings ops)
 {
  UseSingleDeck = ops.HasFlag(CardDeckSettings.SingleDeck);
  UseBigPics = ops.HasFlag(CardDeckSettings.LargePictures);
  UseFancyNumbers = ops.HasFlag(CardDeckSettings.FancyNumbers);
  UseAnimation = ops.HasFlag(CardDeckSettings.Animation);
  CardDeckSettings testFlags = CardDeckSettings.Animation | CardDeckSettings.FancyNumbers;
  UseAnimationAndFancyNumbers = ops.HasFlag(testFlags);
 }

 static void PrintOptions()
 {
  Console.WriteLine("Option settings:");
  Console.WriteLine(" Use Single Deck - " + UseSingleDeck);
  Console.WriteLine(" Use Large Pictures - " + UseBigPics);
  Console.WriteLine(" Use Fancy Numbers - " + UseFancyNumbers);
  Console.WriteLine(" Show Animation - " + UseAnimation);
  Console.WriteLine(" Show Animation and FancyNumbers - " + UseAnimationAndFancyNumbers);
 }

 static void Main()
 {
  CardDeckSettings ops = CardDeckSettings.SingleDeck | CardDeckSettings.FancyNumbers | CardDeckSettings.Animation;
  SetOptions(ops);
  PrintOptions();
  Console.Read();
 }
}

This code produces the following output:
Option settings:
 Use Single Deck - True
 Use Large Pictures - False
 Use Fancy Numbers - True
 Show Animation - True
 Show Animation and FancyNumbers - True

0 comments:

Post a Comment