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


当前回答

上述使用int常量类的解决方案缺乏类型安全。也就是说,你可以发明一些在课堂上没有定义的新值。 此外,举例来说,编写以这些类之一作为输入的方法是不可能的。

你需要写

public void DoSomethingMeaningFull(int consumeValue) ...

但是,在以前的Java中有一个基于类的解决方案,当时没有可用的枚举。这提供了几乎类似枚举的行为。唯一需要注意的是,这些常量不能在switch语句中使用。

public class MyBaseEnum
{
    public static readonly MyBaseEnum A = new MyBaseEnum( 1 );
    public static readonly MyBaseEnum B = new MyBaseEnum( 2 );
    public static readonly MyBaseEnum C = new MyBaseEnum( 3 );

    public int InternalValue { get; protected set; }

    protected MyBaseEnum( int internalValue )
    {
        this.InternalValue = internalValue;
    }
}

public class MyEnum : MyBaseEnum
{
    public static readonly MyEnum D = new MyEnum( 4 );
    public static readonly MyEnum E = new MyEnum( 5 );

    protected MyEnum( int internalValue ) : base( internalValue )
    {
        // Nothing
    }
}

[TestMethod]
public void EnumTest()
{
    this.DoSomethingMeaningful( MyEnum.A );
}

private void DoSomethingMeaningful( MyBaseEnum enumValue )
{
    // ...
    if( enumValue == MyEnum.A ) { /* ... */ }
    else if (enumValue == MyEnum.B) { /* ... */ }
    // ...
}

其他回答

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

你可以这样做:

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类型。

上述使用int常量类的解决方案缺乏类型安全。也就是说,你可以发明一些在课堂上没有定义的新值。 此外,举例来说,编写以这些类之一作为输入的方法是不可能的。

你需要写

public void DoSomethingMeaningFull(int consumeValue) ...

但是,在以前的Java中有一个基于类的解决方案,当时没有可用的枚举。这提供了几乎类似枚举的行为。唯一需要注意的是,这些常量不能在switch语句中使用。

public class MyBaseEnum
{
    public static readonly MyBaseEnum A = new MyBaseEnum( 1 );
    public static readonly MyBaseEnum B = new MyBaseEnum( 2 );
    public static readonly MyBaseEnum C = new MyBaseEnum( 3 );

    public int InternalValue { get; protected set; }

    protected MyBaseEnum( int internalValue )
    {
        this.InternalValue = internalValue;
    }
}

public class MyEnum : MyBaseEnum
{
    public static readonly MyEnum D = new MyEnum( 4 );
    public static readonly MyEnum E = new MyEnum( 5 );

    protected MyEnum( int internalValue ) : base( internalValue )
    {
        // Nothing
    }
}

[TestMethod]
public void EnumTest()
{
    this.DoSomethingMeaningful( MyEnum.A );
}

private void DoSomethingMeaningful( MyBaseEnum enumValue )
{
    // ...
    if( enumValue == MyEnum.A ) { /* ... */ }
    else if (enumValue == MyEnum.B) { /* ... */ }
    // ...
}

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

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

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

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;

另一个可能的解决方案:

public enum @base
{
    x,
    y,
    z
}

public enum consume
{
    x = @base.x,
    y = @base.y,
    z = @base.z,

    a,b,c
}

// TODO: Add a unit-test to check that if @base and consume are aligned

HTH