CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: Enum Usability

Hybrid View

  1. #1
    Join Date
    Jul 2014
    Posts
    12

    Enum Usability

    Ok, so I have been working with enums lately, and have come across a few different uses for them, and for the most part, I see how they can be useful.

    The problem is that in some cases, the uses seem a little forced, and I am wondering if I am missing something. The main point I am speaking to is the use of bitwise operators to create what amount to arrays as far as I can tell:

    Code:
    enum tasks
        {
            task = 1,
            objective = 2,
            mission = 4,
            milestone = 8,
            all = task | objective | mission | milestone
        }
    The above allows me to use the bitwise '&' as follows:

    Code:
    Console.WriteLine(((int)tasks.objective & (int)tasks.all) == 2);
    The example I read was using it in a permissions scenario, using a method to check if the permissions fed into the method match a specific enum and returning a true or false.

    That is all and good, but I don't understand why it is better than creating an array or list of values and just running it against that:

    Code:
    List<string> myList = new List<string>() { "task", "objective", "mission","milestone" };
    //OR
    //string[] myArray = { "task", "objective", "mission", "milestone" };
    Console.WriteLine(myList.Contains("mission"));
    I figure I might be limiting the potential use cases, but my immediate thought is generally that of validating user input. Of course, that would involve a little more code (i.e. converting to same case, etc.), but I think that is irrelevant because both solutions would be similarly affected.

    Am I missing something about the value of treating enums in that way?

  2. #2
    Join Date
    Jul 2014
    Posts
    12

    Re: Enum Usability

    Are you guys all sitting back thinking what a knucklehead I must be?

  3. #3
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enum Usability

    If you have a fixed number of items that don't change very often the enums are great. If you use them as flags with the [Flags] attribute, you can pass a single variable to a method rather than multiple Boolean variables (such as bool isTask, bool isObjective, ...).

    In general, it's easier to compare an enum rather that a string (and faster).

    If you have a large numbers of items to track (or the items are constantly changing), then an enum may not be the way to go.

    One last benefit of an enum is that you get a compiler error if you rename it (where you may not if you use a string).

  4. #4
    Join Date
    Jul 2014
    Posts
    12

    Re: Enum Usability

    Understood, and thanks - that actually kind of clears the fog on when Enums are a good idea. I had read about [Flags] and played around with it a bit, but I will need to do some exploration to understand the passing of a single variable rather than several bool variables.

    Quote Originally Posted by Arjay View Post
    In general, it's easier to compare an enum rather that a string (and faster).
    What do you mean by this?

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enum Usability

    Quote Originally Posted by decimer View Post
    Understood, and thanks - that actually kind of clears the fog on when Enums are a good idea. I had read about [Flags] and played around with it a bit, but I will need to do some exploration to understand the passing of a single variable rather than several bool variables.



    What do you mean by this?
    Consider...
    Code:
    enum Color { Red, Green, Blue }
    
    var color = Color.Red;
    
    if(color == Color.Red)
    {
      // do something with red
    }
    vs. using strings.
    Code:
    string color = "red";
    
    if(color == "Red")
    {
      // do something with red
    }
    In the string case, I intentionally introduced a bug by changing the casing on "Red" (vs. "red").

    If you compare strings, then you have to make sure that the casing is the same, perform a ToUpper or ToLower before the comparison or compare as case insensitive.

    In short, there is much more to keep track of when using strings.

    Another important consideration is try to structure the code such that a mistake is a compiler error rather than a runtime error.

    If you have the Color enum and type Color.red, it is going to be a compiler error and you know immediately (actually intellisense will highlight it for you before the compile).

    But this isn't true if you use strings. With a string, any error in the comparison won't be caught until runtime (and runtime errors are definitely less desirable than compile time errors).

    I generally prefer using an enum unless I have a reason not to (like many enum items, or something that isn't a fixed number of items as I mentioned earlier).

  6. #6
    Join Date
    Jul 2014
    Posts
    12

    Re: Enum Usability

    I looked at [Flags] and instantly remembered that it is the instance in which the bitwise operators came into play for making comparisons. I take it that you are suggesting something like a switch statement inside a method to accept the enum and make those comparisons?

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enum Usability

    Quote Originally Posted by decimer View Post
    I looked at [Flags] and instantly remembered that it is the instance in which the bitwise operators came into play for making comparisons. I take it that you are suggesting something like a switch statement inside a method to accept the enum and make those comparisons?
    Sure. Keep in mind that if you are using flags, you need to mark the enum with the [Flags] attribute and set each enum entry's value as 2's compliment (0,1,2,4,8,16, etc.). Then you can write code like:

    Code:
    [Flags]
    enum Tasks
    {
            None = 0,
            Task = 1,
            Objective = 2,
            Mission = 4,
            Milestone = 8,
            All = Task | Objective | Mission | Milestone
    }
    
    var tasks = Tasks.Objective | Tasks.Mission;
    
    if((tasks & Tasks.Mission) == Tasks.Mission)
    {
      // you have a mission
    }
    Better yet, write a helper method
    Code:
    static bool HasTaskFlag(Tasks tasks, Tasks flag)
    {
      return ((tasks & flag) == flag);
    }
    You'll notice that I change the formatting of your original tasks declaration. I do this because C# style naming convensions for enums are the enum and its members are all PascalCased. Plural name (i.e. Tasks) are okay for [Flags] enums, but singular is used when an enum doesn't have the [Flags] attribute.

    So a non flags colors enum would be defined as
    Code:
    public enum Color
    {
      Red, // if you don't specify a value, C# starts at 0
      Green,
      Blue
    }

  8. #8
    Join Date
    Jul 2014
    Posts
    12

    Re: Enum Usability

    ...but you still need to do the case check on an enum comparison, correct?

  9. #9
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enum Usability

    Quote Originally Posted by decimer View Post
    ...but you still need to do the case check on an enum comparison, correct?
    I'm not following. If you are making a comparison, then you need to write the logic to make the comparison. You'll will still need an if statement or switch statement for the comparison (I'm not saying you don't).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured