What is the best way to "override" enums?

53,848

Solution 1

The other answers are true, if you don't own or can't modify the original base class or enumeration. If you can, then you could use the typesafe enum pattern. It allows you to define your own enum types, not derived from enum, that do whatever you want them to do (including support inheritance).

public class MyEnum
{
  public static readonly MyEnum A = new MyEnum("A");
  public static readonly MyEnum B = new MyEnum("B");
  public static readonly MyEnum C = new MyEnum("C");

  public override string ToString()
  {
    return Value;
  }

  protected MyEnum(string value)
  {
    this.Value = value;
  }

  public string Value { get; private set; }
}

public sealed class MyDerivedEnum : MyEnum
{
  public static readonly MyDerivedEnum D = new MyDerivedEnum("D");

  private MyDerivedEnum(string value)
    : base(value)
  {
  }
}

class Program
{
    static void Main(string[] args)
    {
        MyEnum blah = MyEnum.A;
        System.Console.WriteLine(blah);
        blah = MyDerivedEnum.D;
        System.Console.WriteLine(blah);
    }
}

A
D
Press any key to continue . . .

Solution 2

Classes let you override virtual methods only, not override fields/inner classes/enums. You can hide an inner enum using the new keyword, but any method which requires the enum of the base class is incompatible with the enum of the child class.

    class Base
    {
        public enum myEnum
        {
            hello, to, you
        }

        public void doIt(myEnum e)
        {
            Console.Out.WriteLine(e);
        }

        static void Main(string[] args)
        {
            Base a = new Child();
            a.doIt(Child.myEnum.hello); // this is a syntax error because doIt requires a Base.myEnum, not a Child.myEnum.
        }
    }

    class Child : Base
    {
        public new enum myEnum
        {
                hello, my, dear
        }
    }

Solution 3

You can use the "new" keyword to override the field you defined in the base class.

class Base
{
   public MyEnum A = MyEnum.Default;
}

class Derived : Base
{
   public new MyEnum A = MyEnum.Changed;
}
Share:
53,848
Tyler Treat
Author by

Tyler Treat

Managing Partner at Real Kinetic helping companies build cloud software. Interested in distributed systems, messaging infrastructure, and resilience engineering.

Updated on January 16, 2020

Comments

  • Tyler Treat
    Tyler Treat over 4 years

    Possible Duplicate:
    Enum “Inheritance”

    I have a number of classes which extend an abstract class. The abstract parent class defines an enum with a set of values. Some of the subclasses inherit the parent class's enum values, but some of the subclasses need the enum values to be different. Is there any way to somehow override the enum for these particular subclasses, and if not, what is a good way to achieve what I'm describing?

    class ParentClass
    {
        private MyEnum m_EnumVal;
        public virtual MyEnum EnumVal
        {
            get { return m_EnumVal; }
            set { m_EnumVal = value; }
        }
    
        public enum MyEnum { a, b, c };
    }
    
    class ChildClass : ParentClass
    {
        private MyEnum m_EnumVal;
        public virtual MyEnum EnumVal
        {
            get { return m_EnumVal; }
            set { m_EnumVal = value; }
        }
    
        public enum MyEnum { d, e, f };
    }
    
  • Tyler Treat
    Tyler Treat over 13 years
    I used this, and it says it hides the inherited member. Is there a difference between hiding and overriding? Why can't the override keyword be used with enums?
  • Cheng Chen
    Cheng Chen over 13 years
    virtual and override are used for methods, not fields.
  • Tyler Treat
    Tyler Treat over 13 years
    The problem is I the classes also have a field for a value from the enum, so I run into this: 'ChildClass.EnumValue': type must be 'ParentClass.MyEnum' to match overridden member 'ParentClass.EnumValue'
  • Tyler Treat
    Tyler Treat over 13 years
    The incompatibility issue you mention is a problem I'm facing. How could I avoid this?
  • helloworld922
    helloworld922 over 13 years
    Using enums, it's not possible. You can create your own class with a bunch of pre-defined constant values and then extend that class. However, this cannot erase any values in the base class (redefinition should be ok depending on how it's done), only add to it. See bstn's link posted under the original question.
  • Cheng Chen
    Cheng Chen over 13 years
    @Tyler: Please provide some code.
  • Merlyn Morgan-Graham
    Merlyn Morgan-Graham over 13 years
    Now that I checked, this is nearly duplicate to an answer on the other thread. I guess this really is a duplicate question...
  • Machtyn
    Machtyn about 9 years
    Well, I heavily relied on your answer to really comprehend the answer given on the other page. I had all 3 code sets set next to each other (thanks large screen!) and studied it out. Thanks! Next step: Figure out how to make the "MyEnum" enumerable.
  • Adrian Frielinghaus
    Adrian Frielinghaus over 7 years
    Saved my day, thanks!
  • Roberto
    Roberto over 7 years
    Perhaps you could provide a more hidden enum in the base class with all possible values, you'd use it to create Base.MyEnum and the new Derived.MyEnum. Ugly but...
  • LarryBud
    LarryBud over 5 years
    The thing is, if you do own the base class, then why not just add whatever enums you need?
  • Merlyn Morgan-Graham
    Merlyn Morgan-Graham over 5 years
    @larrybud that works well enough when an enum does absolutely everything you'd want it to, and when every person in the future who will want new enumerated values will be able to/allowed to touch the base code. If you need to add additional abstract interface (e.g. type conversions your language doesn't support for enums), or need/want to follow the open/closed principle (Google open/closed principle. There's a wikipedia article that won't link properly here), then using a class is the way to go.