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,它们将结构定义为枚举。该服务不可更改。


当前回答

你可以通过类实现你想要的:

public class Base
{
    public const int A = 1;
    public const int B = 2;
    public const int C = 3;
}
public class Consume : Base
{
    public const int D = 4;
    public const int E = 5;
}

现在你可以像使用枚举一样使用这些类:

int i = Consume.B;

更新(在您更新问题后):

如果你将相同的int值赋给现有枚举中定义的常量,那么你可以在枚举和常量之间进行类型转换,例如:

public enum SomeEnum // this is the existing enum (from WSDL)
{
    A = 1,
    B = 2,
    ...
}
public class Base
{
    public const int A = (int)SomeEnum.A;
    //...
}
public class Consume : Base
{
    public const int D = 4;
    public const int E = 5;
}

// where you have to use the enum, use a cast:
SomeEnum e = (SomeEnum)Consume.B;

其他回答

您可以在enum中执行继承,但它仅限于以下类型。 Int, uint, byte, sbyte, short, ushort, long, ulong

E.g.

public enum Car:int{
Toyota,
Benz,
}

忽略base是保留字的事实,你不能继承enum。

你能做的最好的事情就是这样:

public enum Baseenum
{
   x, y, z
}

public enum Consume
{
   x = Baseenum.x,
   y = Baseenum.y,
   z = Baseenum.z
}

public void Test()
{
   Baseenum a = Baseenum.x;
   Consume newA = (Consume) a;

   if ((Int32) a == (Int32) newA)
   {
   MessageBox.Show(newA.ToString());
   }
}

因为它们都是相同的基类型(即:int),你可以将一个类型的实例的值赋给另一个类型,这就是强制转换。虽然不理想,但很有效。

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

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

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

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

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

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

我知道我来这个派对有点晚了,但这是我的意见。

我们都很清楚,框架不支持Enum继承。在这篇文章中提出了一些非常有趣的解决办法,但没有一个是我想要的,所以我自己尝试了一下。

介绍:ObjectEnum

您可以在这里查看代码和文档:https://github.com/dimi3tron/ObjectEnum。

软件包在这里:https://www.nuget.org/packages/ObjectEnum

或者直接安装它:install - package ObjectEnum

简而言之,ObjectEnum<TEnum>充当任何enum的包装器。通过重写子类中的GetDefinedValues(),可以指定哪些enum值对这个特定的类有效。

添加了许多操作符重载,以使ObjectEnum<TEnum>实例的行为就像底层枚举的实例一样,记住已定义的值限制。这意味着您可以轻松地将实例与int或enum值进行比较,从而在开关情况或任何其他条件中使用它。

我想参考上面提到的github回购的例子和进一步的信息。

我希望这对你有用。请随意评论或在github上打开一个问题以获得进一步的想法或评论。

下面是几个简短的例子,说明你可以用ObjectEnum<TEnum>做什么:

var sunday = new WorkDay(DayOfWeek.Sunday); //throws exception
var monday = new WorkDay(DayOfWeek.Monday); //works fine
var label = $"{monday} is day {(int)monday}." //produces: "Monday is day 1."
var mondayIsAlwaysMonday = monday == DayOfWeek.Monday; //true, sorry...

var friday = new WorkDay(DayOfWeek.Friday);

switch((DayOfWeek)friday){
    case DayOfWeek.Monday:
        //do something monday related
        break;
        /*...*/
    case DayOfWeek.Friday:
        //do something friday related
        break;
}