views:

249

answers:

3

Hi,

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.

+1  A: 

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.

Mitch Wheat
The enum is an integer type. I want to be able to add more members to the enum in the derived classes and have the derived classes only be able to access those members declared in that class and in the super class.
link664
+1  A: 

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.

Rex M
you don need all those Exit Selects. Its not cascading anyway
Pondidum
A: 

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){}
}
Beatles1692