An Enum is used where a variable needs to be constrained to a fixed set of values.
The problem that Enum is trying to solve
Suppose I have a class as shown below
How do I make sure that the property "Privilege" can have only one of these values
One way to do this would be to alter the class User
You can see that if you are trying to set the Privilege property of the user class, you have to always look it up. Also the Privilege being a string, ideally the case should also be considered (which was not done in the set above). Setting Privilege to be an int instead of a string, will take care of case sensitivity problem, but then the problem that they still have to always look up the values before assigning it, remains. It also makes it harder for someone trying to read the code. For example if you read a line of code
it would mean nothing until you look up what the meaning of 1 is supposed to be here.
The bottom line is that whether we use string or int for Privilege, either way the code is hard to use and read.
How Enum makes it better
Now consider this code below
The advantages of doing it this way are
1>The code is easier to read
For instance
myUser.Privilege = UserPrivilege.Admin;
tells who ever reads the code that the privilege of the user is Admin.
2>The code intellisense aware
So there is no need to look up the possible values for Privileges.
3>Any illegal assignment can be caught at compile time.
If you try something like
myUser.Privilege = UserPrivilege.Hero;
it will be caught at compile time.
Note here that every Enum value has a string and integer value. So
myUser.Privilege.ToString() gives you "Admin"
and
(int)myUser.Privilege gives you 4.
How to cast a string into an enum?
In the line of code below, I am casting the string "Admin" into an enum value of the type UserPrivilege.
var foo = (UserPrivilege)Enum.Parse(typeof(UserPrivilege), "Admin");
How to cast an int into an enum?
In the line of code below foo gets set to UserPrivilege.AverageUser
var foo = (UserPrivilege)2;
However note here that casting an int to an enum always succeeds, even if that enum value does not actually exist. For example you could do
var foo=(UserPrivilege)9999;
Although no defined UserPrivilege has a value of 9999, the above line of code will run.
How to check if an enum value is valid?
To check if the enum is valid, do this
var foo=(UserPrivilege)9999;
Enum.IsDefined(typeof (UserPrivilege), foo);//returns false
How to loop thru a list of enums?
foreach (UserPrivilege privilege in Enum.GetValues(typeof(UserPrivilege)))
{
Console.WriteLine(privilege);
}
The problem that Enum is trying to solve
Suppose I have a class as shown below
public class User { public string FirstName { get; set; } public string LastName { get; set; } public string Privilege { get; set; } }
How do I make sure that the property "Privilege" can have only one of these values
- NewUser
- AverageUser
- SuperUser
- Admin
One way to do this would be to alter the class User
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication { public class User { public string _privilege; public string FirstName { get; set; } public string LastName { get; set; } public string Privilege { get { return _privilege; } set { _privilege = value; if (_privilege != "NewUser" && _privilege != "AverageUser" && _privilege != "SuperUser" && _privilege != "Admin") { throw new Exception("Sorry that value for privilege is not acceptable"); } } } } class Program { static void Main(string[] args) { var myUser = new User(); myUser.FirstName = "Dilbert"; myUser.LastName = "DotNet"; myUser.Privilege = "Admin"; } } }
You can see that if you are trying to set the Privilege property of the user class, you have to always look it up. Also the Privilege being a string, ideally the case should also be considered (which was not done in the set above). Setting Privilege to be an int instead of a string, will take care of case sensitivity problem, but then the problem that they still have to always look up the values before assigning it, remains. It also makes it harder for someone trying to read the code. For example if you read a line of code
myUser.Privilege =1
it would mean nothing until you look up what the meaning of 1 is supposed to be here.
The bottom line is that whether we use string or int for Privilege, either way the code is hard to use and read.
How Enum makes it better
Now consider this code below
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication { public enum UserPrivilege { NewUser = 1, AverageUser = 2, SuperUser = 3, Admin = 4 } public class User { public string FirstName { get; set; } public string LastName { get; set; } public UserPrivilege Privilege { get; set; } } class Program { static void Main(string[] args) { var myUser = new User(); myUser.FirstName = "Dilbert"; myUser.LastName = "DotNet"; myUser.Privilege = UserPrivilege.Admin; } } }
The advantages of doing it this way are
1>The code is easier to read
For instance
myUser.Privilege = UserPrivilege.Admin;
tells who ever reads the code that the privilege of the user is Admin.
2>The code intellisense aware
So there is no need to look up the possible values for Privileges.
3>Any illegal assignment can be caught at compile time.
If you try something like
myUser.Privilege = UserPrivilege.Hero;
it will be caught at compile time.
Note here that every Enum value has a string and integer value. So
myUser.Privilege.ToString() gives you "Admin"
and
(int)myUser.Privilege gives you 4.
How to cast a string into an enum?
In the line of code below, I am casting the string "Admin" into an enum value of the type UserPrivilege.
var foo = (UserPrivilege)Enum.Parse(typeof(UserPrivilege), "Admin");
How to cast an int into an enum?
In the line of code below foo gets set to UserPrivilege.AverageUser
var foo = (UserPrivilege)2;
However note here that casting an int to an enum always succeeds, even if that enum value does not actually exist. For example you could do
var foo=(UserPrivilege)9999;
Although no defined UserPrivilege has a value of 9999, the above line of code will run.
How to check if an enum value is valid?
To check if the enum is valid, do this
var foo=(UserPrivilege)9999;
Enum.IsDefined(typeof (UserPrivilege), foo);//returns false
How to loop thru a list of enums?
foreach (UserPrivilege privilege in Enum.GetValues(typeof(UserPrivilege)))
{
Console.WriteLine(privilege);
}