DQbJA%9hy9hmhx'mhx'DQbJA%{XybmXx{['mXx{['JAyyyy%9yy95aj[hQ5aQ5aDQbJA{|h{|h{|h%9Hg|Xym|X{Khp'9H|Xym|X{['{7{{7?hHhff{h|hK{|hKh JA{zhy{{{%{_yq9hj{{9khy{kQ'}{yQ'}DQbJAb%9_y'DQbJAb%{y'QJA%yNjhJA%yaABbEBABDBEBrDrreX-~~| 76565454VC~W 7G756464VCC 77G757597VBXC~BZZZC~ 766665646564657G7G7VCCCP7-~B-~B~C 7666669996494V~~B~ 764VBCC 9V 7F5 7ZZZX-

Enum.` In the forest a flower grows. This flower has many attributes. It is blooming. It is pink (not blue or yellow). A gentle wind passes through the region.`With an enum,` we can classify this plant. Consider that flowers come in all colors. It could use FlowerColor.Pink. Another one could be Blue.`Enum example.` Here is an enum that expresses importance. An enum type internally contains an enumerator list. The values (like Trivial and Critical) are ints like 1 and 4. `Int: `The underlying value of this enum is the default, which is int. When we use an Importance variable, we are using an int.`If: `We test the enum value with an if-statement that includes an if-else block. The value is Critical, so "True" is printed.`Enum advantages.` With an enum, magic constants are separate. This modular design makes things easier to understand. Fewer bugs will be introduced. `Enums can be used with IntelliSense in Visual Studio. This feature will guess the value you are typing.`Press tab: `We can simply press tab and select the enum type we want. This is an advantage to using enum types.`Debugger.` We examine what enums look like in the Visual Studio debugger. We see that enums are strongly-typed. You cannot assign them to just any value. `The debugger shows that "tagValue" is of type Program.TagType. Internally it is represented as an integer.`Strings.` We convert enums to strings for display on the Console. Enum values always have a name, such as TagType.None (in the above example). `To print out the enum values, you can call ToString on the enum variable in a program.`Another method such as Console.WriteLine can automatically call the ToString method.`ToString.` Console.WriteLine will call the ToString method on all types passed to it. Internally, ToString invokes methods that use reflection to acquire the string representation. `Enum ToString `enum-tostring`A warning.` Some examples here use short, letter-based identifiers (b1, v2) for variables. These are not ideal. It is better to use more descriptive words, such as "animal" or "visibility."`Parse.` Sometimes we have a string value that we want to convert to an equivalent enum. This could happen when accepting user input. `When using the .NET Framework, calling a built-in method to do conversions (where one exists) is usually best.`Enum.Parse: `The tricky part of using this method involves typeof and casting. It is best to avoid this if possible.`Enum.Parse `enum-parse`GetName, Getnames.` Built-in methods get strings that represent enums. With GetName, we can get the name for an enum value. With GetNames we get all the string representations at once. `Enum.GetName `enum-getname`Format enums.` It is possible to format the values stored in enums in different ways. We can display an integer representation, or a hex representation. `Enum.Format `enum-format`Switch.` The above examples show if-statements used with enums. But switch in the C# language is sometimes compiled to more efficient IL. `Switch Enum `switch-enum`The IsFormat method works as a filter that tells us something about sets of enum values.`Logic: `We can separate the logic here instead of repeating ourselves. This helps clarify the program logic.`Default.` Values are always initialized to zero when they are fields of a class. Upon class creation, an enum field will also be initialized to zero (and the equivalent value). `To make enums valid, always use the default value of zero. This way, we can test for the default value of fields.`Sometimes: `This issue is not worth fixing. But it is often useful for verifying correctness.`You can place a semicolon at the end of an enum block (but this is not required or helpful usually).`FxCop.` This is a code analysis tool released by Microsoft. It helps us improve certain issues in code. It will tell us that "enums should have zero value." `Quote: `A non-flags attributed enumeration should define a member with the value of zero so that the default value is a valid value of the enumeration. If appropriate, name the member None.`Enums should have zero value: microsoft.com `https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/ms182149(v=vs.80)`Collections.` Here we apply the Stack collection in the .NET Framework. With Stack, we can develop a parser that keeps the most recently encountered enum value on the top. `Stack: `The Stack here can only have TagType values added to it. This is an example of type checking and validation.`Stack `stack`Pop: `With the Pop method we get the top element from the stack. This is of type TagType.ItalicsTag.`Result: `In the execution of this program, the stack has two enums added and one removed.`Type.` An enum has an underlying type. Each time we use the enum, we are using the underlying type. The enum has syntactic sugar on top. `Int: `Enums are by default an int type, but we can adjust this to a different numeric type.`Byte: `Here we create an enum with a type of byte. This is sometimes useful on small enums. A byte can only contain 256 different values.`Byte `byte`Memory: `The CoffeeSize enum will use memory equivalent to a byte. This can make classes more efficient and smaller.`GetUnderlyingType.` We can determine an enum's type (like int) at runtime. Enum.GetUnderlyingType, a static method, determines the underlying type. `Static Method `static`Next: `We declare an enum Importance. For this example it uses an underlying type of byte.`Then: `When the GetUnderlyingType method is called, the System.Byte type is returned.`Null, none.` An enum value cannot be null. It is a value type like an int. To avoid the "cannot convert null" error, use a special None constant as the first enum item. `Flags.` The language allows us to specify a Flags attribute on an enum. This enables the enum to be used as a bit field. We can use combinations of enum values this way. `Flags `enum-flags`Arrays.` Enums are values. We can use enums to index arrays. This approach is useful for some kinds of tables or data structures in programs. `Enum Array `enum-array`Performance.` Enums are fast. They are almost never a performance concern. They are just syntactic sugar on a type like int, which is also fast. `Enum Performance `enum-performance`Memory.` Suppose we develop a class that has an enum field. The underlying type of this enum contributes to how much memory the class will use.`Memory, continued.` A smaller type (such as byte) will make class instances that hold the enum smaller. Thousands of class instances are required before this optimization is important.`A review.` Enums enhance clarity and reduce the probability of invalid constants. We use them to represent constant values (such as integers) in a consistent way.

XYZ YYYYY { XZenumZ Importance X{ XXNone, XXTrivial, XXRegular, XXImportant, XXCritical X} XYX{Z XXYAn enum local variable. XXZImportance YYZImportance.CriticalZ;Z XXYTest against known Importance Ys. XXZYYYZImportance.TrivialZ) XX{ XXXYZ"Not true"Z); XX} XXelse YYYZImportance.CriticalZ) XX{ XXXYZ"True"Z); XX} X} } Z TrueZ YYYYY { XZenumZ TagType X{ XXNone, XXBoldTag, XXItalicsTag, XXHyperlinkTag, X} XYX{Z XXYSpecify a tag instance. XXZTagTypeZ tagYYZTagType.BoldTagZYXXYtagYYTagType.BoldTag) XX{Z XXXYWill be Yed. XXXZYZ"Bold"Z); XX} XXYtagYYTagType.HyperlinkTag) XX{Z XXXYThis is not Yed. XXXZYZ"Not true"Z); XX} X} } Z BoldZ YY { XZenumZ Visibility X{ XXNone, XXHiddenY2, XXVisibleY4 X} XZenumZ AnimalType X{ XXNone, XXCatY1, XXDogY2 X} XYX{Z XXYTwo enum variables. XXZAnimalTypeZ animalYZAnimalType.DogZ; XXZVisibilityZ visibleYZVisibility.HiddenZ;Z XXYUse Y.YLineYY out heir Ys. XXZY.Y.ZYLineZ(animal); XXY.Y.ZYLineZ(visible); X} } Z Dog HiddenZ YYYYY { XZenumZ FormatType X{ XXNone, XXBoldFormat,ZXYIs a Ymat Y. XXZItalicsFormat,Z YIs a Ymat Y. XXZHyperlinkZX YNot a Ymat Y. XZ} XYX{Z XXYTest enum with Y mY. XXZFormatType YmatYYFormatType.None; XXYZIsFormatZ(YmatY)) XX{Z XXXYThis is not reached, as None does not Y a true YYIsFormat. XXXZYZ"Error"Z); XX}Z XXYTest another enum with Y. XXZYmatYYFormatType.ItalicsFormat; XXYZIsFormatZ(YmatY)) XX{Z XXXYThis is Yed, as we receive true from IsFormat. XXXZYZ"True"Z); XX} X}Z X/Y<Y> X/YReturns true if the FormatType is Bold or Italics. X/Y</Y> XZYbool ZIsFormatZ(FormatType Y) X{ XXZYZ (Y) XX{ XXXYFormatType.BoldFormat: XXXYFormatType.ItalicsFormat: XXXX{Z XXXXXYThese 2 Ys are Ymat Ys. XXXXXZYZ true; XXXX} XXXdefault: XXXX{Z XXXXXYThe argument is not a Ymat Y. XXXXXZYZ false; XXXX} XX} X} } Z TrueZEnum with default Y of NoneZ ZenumZ E { XNone, XA, XB, XC };Z Y YY { XZenumZ TagType X{ XXNone,ZXX YYeger YY0 XXZBoldTag,ZX Y1 XXZItalicsTag,Z Y2 XXZHyperlinkTag,Z Y3 XZ} XYX{Z XXYCY a Stack of enums. XXZvar stackYYStack<TagType>();Z XXYAdd enum YsYour Stack. XXZstack.ZPushZ(TagType.BoldTag);Z YAdd bold. XXZstack.ZPushZ(TagType.ItalicsTag);Z YAdd italics. XXYYthe top enum Y. XXZTagType thisTagYstack.ZPopZ();Z YYtop tag. XXZY.YZ"POP RESULT: "ZYthisTag);Z XXYPeek at the top. XXZvar peekedYstack.ZPeekZ(); XXY.YZ"PEEK RESULT: "ZYpeeked); X} } Z POP RESULT: ItalicsTag PEEK RESULT: BoldTagZ YYYYY { Xenum CoffeeSize : ZbyteZ X{ XXNone, XXTall, XXVenti, XXGrande X}YXYX{Z XXYCY a coffee size local. XXZCoffeeSize sizeYZCoffeeSize.VentiZ; XXYsize); X} } Z VentiZ YYYYY { Xenum Importance : byte X{ XXLow, XXMedium, XXHigh X}YXYX{Z XXYDetermine the underlying type of the enum. XXZType typeYZEnum.GetUnderlyingTypeZ(typeof(Importance)); XXYtype); X} } Z Y.ByteZ enum Color { XNone, XBlue, XRed } YY { XYX{ XXColor cYZnullZ; X} } ZResultsZ ZError CS0037Z Cannot cY nullY'Color' because it is a non-nullable Y type Z enum Color { XNone, XBlue, XRed } YY { XYX{ XXColor cYZColor.NoneZ; X} }Z

)Ucl_`_a1Yenumsenums with Debuggerenums with Console.WriteLineenums in switchenums with Stackunderlying typeGetUnderlyingTypecauses null errorNone enum