2023-09-27 07:00:01

Enum“继承”

我在一个低级名称空间中有一个枚举。我想在中层名称空间中提供一个“继承”低层枚举的类或枚举。

namespace low
{
   public enum base
   {
      x, y, z
   }
}

namespace mid
{
   public enum consume : low.base
   {
   }
}

我希望这是可能的,或者可能有某种类可以取代枚举消费,这将为枚举提供一个抽象层,但仍然让该类的实例访问枚举。

想法吗?

编辑: 我没有在类中将其转换为const的原因之一是我必须使用的服务需要低级枚举。我已经获得了wsdl和xsd,它们将结构定义为枚举。该服务不可更改。


当前回答

This is what I did. What I've done differently is use the same name and the new keyword on the "consuming" enum. Since the name of the enum is the same, you can just mindlessly use it and it will be right. Plus you get intellisense. You just have to manually take care when setting it up that the values are copied over from the base and keep them sync'ed. You can help that along with code comments. This is another reason why in the database when storing enum values I always store the string, not the value. Because if you are using automatically assigned increasing integer values those can change over time.

// Base Class for balls 
public class Ball
{
    // keep synced with subclasses!
    public enum Sizes
    {
        Small,
        Medium,
        Large
    }
}

public class VolleyBall : Ball
{
    // keep synced with base class!
    public new enum Sizes
    {
        Small  = Ball.Sizes.Small,
        Medium = Ball.Sizes.Medium,
        Large  = Ball.Sizes.Large,
        SmallMedium,
        MediumLarge,
        Ginormous
    }
}

其他回答

枚举不能从其他枚举派生,只能从int、uint、short、ushort、long、ulong、byte和sbyte派生。

就像Pascal说的,你可以使用其他枚举的值或常量来初始化一个枚举值,但仅此而已。

这是不可能的。枚举不能从其他枚举继承。事实上,所有枚举都必须从System.Enum继承。c#允许语法改变枚举值的底层表示,这看起来像继承,但实际上它们仍然继承自System.enum。

详细信息请参见CLI规范的8.5.2节。来自规范的相关信息

所有枚举必须从System派生。枚举 因此,所有枚举都是值类型,因此是密封的

这是不可能的(正如@JaredPar已经提到的)。试图用逻辑来解决这个问题是一种糟糕的做法。如果你有一个有枚举的基类,你应该列出所有可能的枚举值,并且类的实现应该使用它知道的值。

例如:假设你有一个基类BaseCatalog,它有一个枚举ProductFormats (Digital, Physical)。然后,您可以有一个MusicCatalog或BookCatalog,可以包含数字和物理产品,但如果类是ClothingCatalog,它应该只包含物理产品。

简短的回答是否定的。如果你想,你可以玩一点:

你可以这样做:

private enum Base
{
    A,
    B,
    C
}

private enum Consume
{
    A = Base.A,
    B = Base.B,
    C = Base.C,
    D,
    E
}

但是,它并没有那么好,因为Base。A !=消费。一个

不过,你总是可以这样做:

public static class Extensions
{
    public static T As<T>(this Consume c) where T : struct
    {
        return (T)System.Enum.Parse(typeof(T), c.ToString(), false);
    }
}

为了在基础和消费之间交叉…

你也可以将枚举的值转换为整数,并将它们比较为整数而不是enum,但这也很糟糕。

扩展方法return应该将其类型转换为T类型。

根据你的情况,你可能不需要派生enum,因为它们基于System.Enum。

使用这段代码,你可以传入任何你喜欢的Enum,并获得它所选的值:

public CommonError FromErrorCode(Enum code)
{
    Code = (int)Enum.Parse(code.GetType(), code.ToString());