When and how should enumeration classes be used, not enumerations?

Recently, a developer started using a class template instead of enumerations in places where enumerations usually fit. Instead, it uses something similar to the following:

internal class Suit { public static readonly Suit Hearts = new Suit(); public static readonly Suit Diamonds = new Suit(); public static readonly Suit Spades = new Suit(); public static readonly Suit Clubs = new Suit(); public static readonly Suit Joker = new Suit(); private static Suit() { } public static bool IsMatch(Suit lhs, Suit rhs) { return lhs.Equals(rhs) || (lhs.Equals(Joker) || rhs.Equals(Joker)); } } 

His reasoning is that it invisibly looks like an enumeration, but allows it to contain methods related to numbering (for example, IsMatch above) contained in the enumeration itself.

He called it the Enumeration class, but that is not what I have ever seen. I wondered what advantages and disadvantages were and where could I find out more information?

thanks

Edit: Another advantage he described is the ability to add a specific implementation of ToString () for enumeration.

+7
source share
3 answers

The main advantage of enumerations is that they are integers with some named values, so they are essentially portable and serializable. Arithmetic and logical operations are also faster listed.

Enumeration classes are used when you need an opaque value that contains additional state information. For example, a general level of data access can have as an interface, for example:

  public static class Dal
 {
     public static Record Query (Operation operation, Parameters parameters);
 }

 var result = Dal.Query (Operation.DoSomething, new DoSomethingParameters {...});

The users of a Dal operation are simply an enumeration of the available operations, but it can contain a connection string, SQL statement or stored procedure, and any other data needed for a general Dal.

Another “general” use is for publicly available modes in the system (state or strategy). From the user's point of view, the mode is an opaque value, but it may contain information or internal functions that are critical to the implementation of the system. A contrived example:

 public class TheSystem
 {
    public SystemMode Mode;
    public void Save ()
    {
       Mode.Save ();
    }
    public SystemDocument Read ()
    {
       return Mode.Read ();
    }
 }

 public abstract class SystemMode
 {
    public static SystemMode ReadOnly = new ReadOnlyMode ();
    public static SystemMode ReadWrite = new ReadWriteMode ();

    internal abstract void Save ();
    internal abstract SystemDocument Read ();

    private class ReadOnlyMode: SystemMode
    {
       internal override void Save () {...}
       internal override SystemDocument Read () {...}
    }

    private class ReadWriteMode: SystemMode
    {
       internal override void Save () {...}
       internal override SystemDocument Read () {...}
    }
 }


 TheSystem.Mode = SystemMode.ReadOnly;

I don’t think that just using the static IsMatch method guarantees not using simple enumerations. Something very similar could be achieved using extension methods in this case.

+1
source

The listings are just fine in a lot of scenarios, but in others they are pretty poor. I usually find some problems with Enums:

  • Enumeration Behavior Scattered Around Application
  • New enumeration values ​​require a shotgun operation.
  • Transfers do not follow the principle of open closure.

When the enumeration behavior is scattered around, we can never return it to the source type, because enumeration types can not have any behavior (or state in this case).

On the other hand, with an enumeration class :

All variations of each type of enumeration can be transferred not only to the enumeration class, but also to each specific subtype.

Enumerations work well in a variety of scenarios, but can quickly collapse inside your domain model. Enumeration classes provide much of the same usability, with the added benefit of becoming a destination for behavior.

Switch statements are no longer needed, as I can push this variability and knowledge, where it is, back inside the model. If for some reason I need to check certain values ​​of an enumeration class, the option is still open to me. This template should not replace all enumerations, but it is nice to have an alternative.

can read here here

+4
source

Enumerations are great for mild status information. For example, your color enumerator (excluding blue) would be good for querying the status of a traffic light. True color along with the whole concept of color and all its baggage (alpha, color space, etc.) It does not matter just what state the light is in. Also, changing your listing a bit to represent the state of the traffic light

 [Flags()] public enum LightColors { unknown = 0, red = 1, yellow = 2, green = 4, green_arrow = 8 } 

The current state of lighting can be set as:

 LightColors c = LightColors.red | LightColors.green_arrow; 

And is requested as:

 if ((c & LightColors.red) == LightColors.red) { //Don't drive } else if ((c & LightColors.green_arrow) == LightColors.green_arrow) { //Turn } 

Elements of a class of a static class will be able to support this plural state without additional functions.

However, static class members are great for commonly used objects. System.Drawing.Color elements are great examples, because they are colors of famous names that have obscure constructors (unless you know your hexadecimal colors). If they were implemented as enumerations, you would have to do something like this every time you wanted to use a value as a color:

 colors c = colors.red; switch (c) { case colors.red: return System.Drawing.Color.FromArgb(255, 0, 0); break; case colors.green: return System.Drawing.Color.FromArgb(0,255,0); break; } 

So, if you have an enumeration and you find that you constantly do the / case / if / else / what switch to get the object, you can use the static members of the class. If you are only asking for the status of something, I will stick with the listings. Also, if you need to transfer data in unsafe mode, enums are likely to survive better than the serialized version of your object.

Link to an old post from this forum: When to use enumerations and when to replace them with a class with static members?

+1
source

All Articles