Search code examples
c#design-patternsswitch-statement

Use switch statement on type-safe enum pattern


I found a good looking example about implementation enums in a different way. That is called type-safe enum pattern I think. I started using it but I realized that I can not use it in a switch statement.

My implementation looks like the following:

public sealed class MyState
{
    private readonly string m_Name;
    private readonly int m_Value;

    public static readonly MyState PASSED= new MyState(1, "OK");
    public static readonly MyState FAILED= new MyState(2, "ERROR");

    private MyState(int value, string name)
    {
        m_Name = name;
        m_Value = value;
    }
    
    public override string ToString()
    {
        return m_Name;
    }
    
    public int GetIntValue()
    {
        return m_Value;
    }
}

What can I add to my class in order to be able to use this pattern in switch statements in C#?
Thanks.


Solution

  • You can try something like this:

    class Program
    {
        static void Main(string[] args)
        {
            Gender gender = Gender.Unknown;
    
            switch (gender)
            {
                case Gender.Enum.Male:
                    break;
                case Gender.Enum.Female:
                    break;
                case Gender.Enum.Unknown:
                    break;
            }
        }
    }
    
    public class Gender : NameValue
    {
        private Gender(int value, string name)
            : base(value, name)
        {
        }
    
        public static readonly Gender Unknown = new Gender(Enum.Unknown, "Unknown");
        public static readonly Gender Male = new Gender(Enum.Male, "Male");
        public static readonly Gender Female = new Gender(Enum.Female, "Female");
        public class Enum
        {
            public const int Unknown = -1;
            public const int Male = 1;
            public const int Female = 2;
        }
    
    }
    
    public abstract class NameValue
    {
        private readonly int _value;
        private readonly string _name;
    
        protected NameValue(int value, string name)
        {
            _value = value;
            _name = name;
        }
    
        public int Value
        {
            get { return _value; }
        }
    
        public string Name
        {
            get { return _name; }
        }
    
        public override string ToString()
        {
            return Name;
        }
        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }
    
        public override bool Equals(object obj)
        {
            NameValue other = obj as NameValue;
            if (ReferenceEquals(other, null)) return false;
            return this.Value == other.Value;
        }
    
        public static implicit operator int(NameValue nameValue)
        {
            return nameValue.Value;
        }
    }