【问题标题】:What is the best way to "override" enums? [duplicate]“覆盖”枚举的最佳方法是什么? [复制]
【发布时间】:2011-06-09 21:43:53
【问题描述】:

可能重复:
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 };
}

【问题讨论】:

  • 不能覆盖枚举,C# 不支持返回类型协方差。您将不得不找到其他方法;这是不可能的。
  • @Cody Gray:我很清楚这一点。我想知道最好的解决方案是什么。

标签: c# inheritance enums


【解决方案1】:

如果您不拥有或无法修改原始基类或枚举,其他答案都是正确的。如果可以,那么您可以使用 typesafe 枚举模式。它允许您定义自己的枚举类型,而不是从枚举派生,这些类型可以执行您希望它们执行的任何操作(包括支持继承)。

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
按任意键继续 。 . .

【讨论】:

  • 现在我检查了,这几乎与另一个线程上的答案重复。我想这确实是一个重复的问题......
  • 好吧,我非常依赖您的回答才能真正理解另一页上给出的答案。我将所有 3 个代码集设置为彼此相邻(感谢大屏幕!)并对其进行了研究。谢谢!下一步:弄清楚如何使“MyEnum”可枚举。
  • 拯救了我的一天,谢谢!
  • 问题是,如果您确实拥有基类,那么为什么不添加您需要的任何枚举?
  • @larrybud 当一个枚举绝对能完成你想要它做的所有事情时,并且当未来每个想要新枚举值的人都能够/允许触及基数时,它就足够好用了代码。如果您需要添加额外的抽象接口(例如,您的语言不支持枚举的类型转换),或者需要/想要遵循开放/封闭原则(谷歌开放/封闭原则。有一篇维基百科文章无法正确链接在这里),然后使用类是要走的路。
【解决方案2】:

类只允许您覆盖虚拟方法,而不是覆盖字段/内部类/枚举。可以使用 new 关键字隐藏内部枚举,但是任何需要基类枚举的方法都与子类的枚举不兼容。

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

【讨论】:

  • 你提到的不兼容问题是我面临的一个问题。我怎样才能避免这种情况?
  • 使用枚举,这是不可能的。您可以使用一堆预定义的常量值创建自己的类,然后扩展该类。但是,这不能删除基类中的任何值(重新定义应该没问题,具体取决于它是如何完成的),只能添加它。请参阅原始问题下发布的 bstn 链接。
【解决方案3】:

您可以使用“new”关键字覆盖您在基类中定义的字段。

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

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

【讨论】:

  • 我用过这个,它说它隐藏了继承的成员。隐藏和覆盖之间有区别吗?为什么override关键字不能和枚举一起使用?
  • virtual 和 override 用于方法,而不是字段。
  • 问题是我的类也有一个来自枚举的值的字段,所以我遇到了这个:'ChildClass.EnumValue': type must be 'ParentClass.MyEnum' to match overridden member 'ParentClass.EnumValue'
  • @Tyler:请提供一些代码。
  • 也许您可以在基类中提供一个更隐藏的枚举,其中包含所有可能的值,您可以使用它来创建Base.MyEnum 和new Derived.MyEnum。丑但是...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 2021-07-18
  • 2011-08-31
相关资源
最近更新 更多