Enums and Constants. Which to use when?

C#Language AgnosticEnums

C# Problem Overview


I was doing some reading on enums and find them very similar to declaring constants. How would I know when to use a constant rather than an enum or vice versa. What are some of the advantages of using enums?

C# Solutions


Solution 1 - C#

Use enums when you want to define a range of values that something can be. Colour is an obvious example like:

public enum Colour
{
    White,
    Red,
    Blue
}

Or maybe a set of possible things like: (Example I stole from here as I'm lazy)

[FlagsAttribute]
enum DistributedChannel
{
  None = 0,
  Transacted = 1,
  Queued = 2,
  Encrypted = 4,
  Persisted = 16,
  FaultTolerant = Transacted | Queued | Persisted
}

Constants should be for a single value, like PI. There isn't a range of PI values, there is just PI.

Other points to consider are:

  • a: Constants don't necessarily indicate a relationship between the constants, whereas an enumeration indicates that something can be one of the set defined by the enum.

  • b: A defined enumeration can help you with type checking when used as an argument. Constants are just values, so they don't provide any additional semantic information.

Solution 2 - C#

What's missing from the other answers is that enums have an integer base type. You can change the default from int to any other integral type except char like:

enum LongEnum : long {
    foo,
    bar,
}

You can cast explicitly from and implicitly to the the base type, which is useful in switch-statements. Beware that one can cast any value of the base type to an enum, even if the enum has no member with the appropriate value. So using always the default section in a switch is a good idea. BTW, .NET itself allows even floating point valued enums, but you can't define them in C#, although I think you can still use them (except in switch).

Furthermore, using enums gives you more type safety. If you intend to use e.g. int constants as method parameters, then I could call the method with any int value. Granted, via casting it can happen with enums, too, but it won't happen accidentally. Worse is the possibility to confuse the order of parameters.

void method(int a, int b) {...}

If constant A only may go into a and constant B only may go into b, then using two different enum types will uncover any misuse during the compilation.

Solution 3 - C#

A constant is a language feature which says that the variable won't change value (so the compiler can do optimisations around that knowledge) where an enum is a specific type.

Constants can be any data type but an enum is an enum.

I use an enum any place where you could have a number of options and want to improve readability of the code. i.e. you could have trace levels as an int with values 0, 1, 2 or as an enum as error, warning and info.

Enum's also have the ability to be used as bitwise operators, i.e. FontStyle.Bold | FontStyle.Italic would give you bold and italic fonts.

Solution 4 - C#

In addition to Robert's answer:

  1. Use enum for a finite set of named values. You don't really care about the numerical value behind each symbol (but you still have the ability to impose them, e.g. for compatibility with a legacy system).

  2. Robert: Yes, Enum's can be used as bit fields. Use the Flags attribute (and make sure members of the enum have suitable numerical values).

Solution 5 - C#

A C# constant is similar to a variable in that it gives a defined name to a value. However, a constant differs from a standard variable because once defined, the value assigned to the constant can never be changed. The chief benefit of constants is their assistance in creating self-documenting code as well as allowing the declaration of key values in a single place, which permits easy maintenance should the value need to be updated and the software recompiled.

Whereas Enumerator lists are useful for defining sequences and states, particularly when there is a natural progression through those states. This is because each constant in the list can be formatted and compared using either its name or value. An enum can also be used to define a limited set of valid values.

Solution 6 - C#

One thing I find handy when using enum instead of const is that you can iterate through the values in an enum, it's much harder to do that with const values.

Solution 7 - C#

If you need integer based values use enums. If you need string based values use structs with Constants.

When you have something like

class x
{
    public string string_value {get;set;}
    publi int int_value  {get;set;}
}

x model = new x();
model.string_value  = struct.some_value;
model.int_value = enum.some_value;

Solution 8 - C#

If you have a set of predefined choices which is not supposed to change (i.e adding more choices etc.) than use enum otherwise consts.

Consider the following:

public class Math
{
    enum Command {none = 0, add =1, subtract = 2} 
    const int none =0, add=1,subtract =2;
    public virtual int Operate(int a, int b, Command command) 
    {
        if (command == Command.add) return a+b;
        if(command == Command.subtract) return a-b;
        return a;
    }
    public virtual int Operate(int a, int b, int command) 
    {
        if (command == add) return a+b;
    if(command==subtract) return a-b;
        return a;
    }
}`

class Math1: Math
{
    public override Operate(int a, int b, int command)
    {
        if(command<3) return base.Operate(a, b, command)
        if(command =3) return a*b;
        if(command==4) return a/b;
        return a;
    }
}

so, using const can allow you to pass a parameter value not defined in const declaration, ie. 3 for multiply and 4 for divide. This is good or bad depends on your logic, sometimes it is not wise to allow the user to pass arbitrary values and receive unexpected result.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDracoView Question on Stackoverflow
Solution 1 - C#Andrew BarrettView Answer on Stackoverflow
Solution 2 - C#JohannesView Answer on Stackoverflow
Solution 3 - C#Robert MacLeanView Answer on Stackoverflow
Solution 4 - C#Serge WautierView Answer on Stackoverflow
Solution 5 - C#simplyharshView Answer on Stackoverflow
Solution 6 - C#David KlempfnerView Answer on Stackoverflow
Solution 7 - C#Alex MView Answer on Stackoverflow
Solution 8 - C#Mukesh AdhvaryuView Answer on Stackoverflow