Каков наилучший способ "переопределить" перечисления?

Возможный дубликат:
Enum "Inheritance"

У меня есть ряд классов, которые расширяют абстрактный класс. Абстрактный родительский класс определяет перечисление с набором значений. Некоторые подклассы наследуют значения перечисления родительского класса, но для некоторых подклассов значения перечисления должны быть разными. Есть ли способ каким-то образом переопределить перечисление для этих конкретных подклассов, а если нет, то какой способ получить то, что я описываю?

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 };
}

Ответ 1

Другие ответы верны, если вы не являетесь владельцем или не можете изменить исходный базовый класс или перечисление. Если вы можете, вы можете использовать шаблон typesafe enum. Он позволяет вам определять свои собственные типы перечислений, а не производные от перечисления, которые делают все, что вы хотите от них (включая наследование поддержки).

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);
    }
}

а
D
Нажмите любую клавишу для продолжения.,.

Ответ 2

Классы позволяют вам переопределять только виртуальные методы, а не переопределять поля/внутренние классы/перечисления. Вы можете скрыть внутреннее перечисление с помощью нового ключевого слова, но любой метод, который требует перечисления базового класса, несовместим с перечислением дочернего класса.

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

Ответ 3

Ключевое слово "новое" можно использовать для переопределения поля, определенного в базовом классе.

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

class Derived : Base
{
   public new MyEnum A = MyEnum.Changed;
}