dnatoli
dnatoli

Reputation: 7012

Declaring Enums across derived classes

I am developing a program in VB.NET.

I have an enum called PriceType that is declared in a super class ItemPriceBase. There are 3 classes that derive from ItemPriceBase - ItemPriceMeasured, ItemPriceNDI and ItemPriceExtraCost. The subset of PriceTypes for these classes are totally unique from each - Measured prices are 1 to 6, NDI prices are 7 to 15 and ExtraCost prices are 16 to 22.

Is there a way declare the enum in the super class and then extend the enum in each of the derived classes so that they only have access to those options, yet I can still access a property in the super class that returns an enum of PriceType?

Thanks, Dane.

Upvotes: 0

Views: 1776

Answers (3)

Beatles1692
Beatles1692

Reputation: 5320

In this kind of scenario I usually use an enum object instead of enum types. For example :

public class BaseEnumType
{
public readonly static BaseEnumType A=new BaseEnumType(0,"A");
public readonly static BaseEnumType B=new BaseEnumType(10,"B");
public readonly static BaseEnumType C=new BaseEnumType(20,"C");
public readonly static BaseEnumType[] AllBase=new []{A,B,C};
public int Value{get;private set;}
public string Name {get;private set;}
protected BaseEnumType(int value,string name)
{
Value=value;
Name=name;
}

}

Then you can derive from this BaseEnumType:

public class ChildEnumType:BaseEnumType
{
public readonly static ChildEnumType D=new ChildEnumType(30,"D");
public readonly static ChildEnumType[] AllChild=new []{A,B,C,D};

protected ChildEnumType(int value,string name):BaseEnumType(value,name){}
}

Upvotes: 0

Rex M
Rex M

Reputation: 144132

Not exactly. Since enums are really just integers, you can do something like this:

Enum BaseTypes
    A = 1
    B
    C
End Enum

'start with an arbitrarily high number to avoid colliding with BaseTypes
Enum DerivedTypes
    D = 10
    E
    F
End Enum

'ditto
Enum OtherDerivedTypes
    G = 20
    H
    I
End Enum

You can pass the derived types into a method expecting the base type by casting them as the base type, e.g. (BaseTypes)DerivedTypes.E This will only work of course assuming you don't do any non-virtual case statements or bound-checking in your BaseClass and your derived classes each override the relevant methods, like so:

Base class:

Private Overridable Sub HandleValue(ByVal val As BaseTypes)
    Select Case val
        Case BaseTypes.A
            'do something
            Exit Select
        Case BaseTypes.B
            'do something else
            Exit Select
    End Select
End Sub

Derived class:

Private Overloads Overrides Sub HandleValues(ByVal val As BaseTypes)
    Select Case DirectCast(val, DerivedTypes)
        Case DerivedTypes.D
            'do something D-ish
            Exit Select
        Case DerivedTypes.E
            'do something E-like
            Exit Select
        Case Else
            'what we got wasnt a DerivedType, pass it off to the base
            MyBase.HandleValues(val)
            Exit Select
    End Select
End Sub

Note this only works for a linear inheritance chain - e.g. it breaks down if there are sibling derived classes on the same level, since it becomes very difficult for them to properly hand off enum values to the correct sibling, rather than a parent who simply deals with a more limited scope.

Generally I would not recommend this approach for open-ended extensibility. As you can see, it is a maintenance nightmare. If you have a well-defined, scoped use set that will be mostly set in stone, then this is workable.

Upvotes: 1

Mitch Wheat
Mitch Wheat

Reputation: 300589

Enums can only use the builtin integer types. You can't derive from an Enum; they are implicitly sealed.

All Enums derive from System.Enum, which derives from System.ValueType, and they are sealed, i.e. you can not derive from them.

Upvotes: 1

Related Questions