17

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 };
}
Community
  • 1
  • 1
Tyler Treat
  • 14,640
  • 15
  • 80
  • 115

3 Answers3

21

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 . . .

Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
  • Now that I checked, this is nearly duplicate to an answer on the other thread. I guess this really is a duplicate question... – Merlyn Morgan-Graham Jan 16 '11 at 07:55
  • 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. – Machtyn Apr 29 '15 at 03:50
  • Saved my day, thanks! – Adrian Frielinghaus Oct 31 '16 at 16:14
  • The thing is, if you do own the base class, then why not just add whatever enums you need? – LarryBud Mar 27 '19 at 13:18
  • 1
    @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. – Merlyn Morgan-Graham Mar 27 '19 at 19:42
6

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
        }
    }
helloworld922
  • 10,801
  • 5
  • 48
  • 85
  • The incompatibility issue you mention is a problem I'm facing. How could I avoid this? – Tyler Treat Jan 16 '11 at 07:12
  • 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. – helloworld922 Jan 16 '11 at 07:16
1

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;
}
Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • 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? – Tyler Treat Jan 16 '11 at 07:01
  • `virtual` and `override` are used for methods, not fields. – Cheng Chen Jan 16 '11 at 07:04
  • 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 Jan 16 '11 at 07:10
  • @Tyler: Please provide some code. – Cheng Chen Jan 16 '11 at 07:38
  • 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... – Roberto Apr 02 '17 at 10:40