Enumerations
An enumeration is a logical grouping of integers that are represented by names. The keyword "enum" is used to declare an enumeration. In C#, the general syntax of declaring an enum is:
enum enumeration-name
{
list of enums
}
The list is a comma separated list of name. Let's see an example.
enum Day
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
Here, we have grouped individual day names in an enum called "Day". Here, each name is assigned with an integer. By default, the integer in an enum starts from 0 and keep increasing in an increment of 1.
So, Sunday is assigned 0, Monday is assigned 1, Tuesday is assigned 2, and so on.
To use an enum, we can simple write enum name followed by a dot (.) followed by one of the names or symbols in the enum. For e.g.
Console.WriteLine(Day.Tuesday);
This will print "Tuesday" in the output console. This is because it returns the string equivalent of the specified symbol of the enum. To get the actual integer values, we need to cast the symbol to int. The below line will print "2" to the output console.
Console.WriteLine((int)Day.Tuesday);
We can also explicitly assign integers to the individual symbols. Suppose in the above example we want to start the name of the day with integer 1. Here is how we can do that.
enum Day
{
Sunday = 1,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
Now, if we try to print the below line, it will print "3" to the output console.
Console.WriteLine((int)Day.Tuesday);
In the below example we have explicitly assigned different integers to all symbols in the enum list.
enum Day
{
Sunday = 10,
Monday = 20,
Tuesday = 30,
Wednesday = 40,
Thursday = 50,
Friday = 60,
Saturday = 70
}
Hence, the following line will print "30" to the output console.
Console.WriteLine((int)Day.Tuesday);
Why enums over strings?
The two important aspects of using enums is that they provides readability and makes code much less prone to errors. Let's see how. Consider the below example.
using System;
enum Day
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Using enums");
Console.WriteLine("");
var isWeekend = CheckWeekend(Day.Wednesday);
Console.WriteLine(isWeekend);
Console.Write("Press any key to continue...");
Console.ReadKey(true);
}
static bool CheckWeekend(Day day)
{
bool isWeekend = false;
switch(day)
{
case Day.Sunday:
case Day.Saturday:
isWeekend = true;
break;
}
return isWeekend;
}
}
The above program checks if a particular day is a weekend or not. It improved readability because we are using English names to represent choices. You might be thinking that the same thing could be done with string as well. The answer is - we prefer enums because it makes code less prone to error. This is because we can't misspell any name of the enum. It will throw a compile-time error. If it had been a string, we could have unintentionally passed this wrong word "Wedsday", and our program would have compiled successfully. However, at runtime, it would not have provided the expected results.
Using other data types with enum
The default data type for enum is an integer. However, C# allows us to change the datatype of enum so that the enum symbols can represent the values of other types to cater to some specific use cases. Let's see the below example.
enum CapacityRange : long
{
Min = 4450L,
Max = 35465L
}
Console.WriteLine($"Our transport system allows minimum load of {(long)CapacityRange.Min} kgs and maximum load of {(long)CapacityRange.Max} kgs.");
Intuitively, we can also say enums as logically organized constants.
Structures
A Structure in C# is used to define a limited number of variables as a group. It is similar to a class in terms of encapsulating data members, however, the fundamental difference is that the structure is a value type data type and class is a reference type data type. This means it is much faster to access than having a class with a similar variable.
Declaring and using structures
A Structure is declared by using "struct" keyword. See the below example.
using System;
struct Student
{
public string name;
public int age;
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Using Structure");
Console.WriteLine("");
Student alice = new Student();
alice.name = "Alice";
alice.age = 26;
Console.WriteLine($"{alice.name}'s age is {alice.age} years.");
Console.Write("Press any key to continue...");
Console.ReadKey(true);
}
}
The above program will print "Alice's age is 26 years.".
Structure with constructor
A structure can have constructors. Consider the below example.
using System;
struct Shape
{
public int length, width, height;
public Shape(int _length, int _width, int _height)
{
length = _length;
width = _width;
height = _height;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Using Structure with constructor");
Console.WriteLine("");
Shape shape = new Shape(20, 30, 40);
Console.WriteLine("Shape's dimensions");
Console.WriteLine($"Length = {shape.length}");
Console.WriteLine($"Width = {shape.width}");
Console.WriteLine($"Height = {shape.height}");
Console.Write("Press any key to continue...");
Console.ReadKey(true);
}
}
The constructor is use to initialize the variables of a structure. Using default constructor in structure initializes the variables with the default values as per their data types.
Properties of structures
Here are some important properties of a structure we must consider before writing some code around structures.
- It is a compile-time error to declare a parameterless constructor in a structure.
- We can not initialize an instance variable inside the structure body.
- A structure can implement interfaces.
- A structure can not inherit from another structure.
- We can create a structure without using new keyword. In this case, we need to initialize all variables of the structure before using it.
- Structures can have variables, methods, constructors, properties, events, indexers, constants, indexers, operators, events, and nested structures.
Choosing structures over classes
We should choose a structure over a class in the following scenarios.
- When we just want to wrap a few variables to create a light-weight user-defined data type, we should consider using structures.
- When we want to use a group of variables to use many times or form a large collection, we should use structures. For e.g. suppose there is a Point class which contains two variables x and y for 2D coordinates and you want to have an array of this class with 10000 Points. Since class uses heaps for reference types instance allocations, allocating such large arrays onto heaps and overhead of maintaining the same by the CLR would hurt performance. Hence, in this scenario, it would be better to use structures instead of classes.
- If we have more of such requirements like using properties, events, methods etc. then as a practice we must consider using classes instead of structures.