I'm trying to create several enums
as such, that gives the syntax of Dropdown.Category.Subcategory
. However, I have been reading that this isn't such a good idea. My choice for this was mostly because I couldn't think of any other way to select different enum
values depending on the choice of the category, and then the choice of the subcategory is subject to the selected enum
based on the enum
values.
Is there a better way to create such functionality? I would prefer to be able to easily identify both the .Category
and .Subcategory
names, and it would be a bonus if this code was readable.
Just to make it clear, I want to be able to choose the Category
, then have an appropriate Subcategory
selection.
public class Dropdown
{
public enum Gifts
{
GreetingCards,
VideoGreetings,
UnusualGifts,
ArtsAndCrafts,
HandmadeJewelry,
GiftsforGeeks,
PostcardsFrom,
RecycledCrafts,
Other
}
public enum GraphicsAndDesign
{
CartoonsAndCaricatures,
LogoDesign,
Illustration,
EbookCoversAndPackages,
WebDesignAndUI,
PhotographyAndPhotoshopping,
PresentationDesign,
FlyersAndBrochures,
BusinessCards,
BannersAndHeaders,
Architecture,
LandingPages,
Other
}
}
Create a class that cannot be inherited from externally, give it several inner classes, each extending from it. Then add static read only variables for each of the values that you want to represent:
public class Dropdown
{
private string value;
//prevent external inheritance
private Dropdown(string value)
{
this.value = value;
}
public class Gifts : Dropdown
{
//prevent external inheritance
private Gifts(string value) : base(value) { }
public static readonly Dropdown GreetingCards =
new Gifts("GreetingCards");
public static readonly Dropdown VideoGreetings =
new Gifts("VideoGreetings");
public static readonly Dropdown UnusualGifts =
new Gifts("UnusualGifts");
public static readonly Dropdown ArtsAndCrafts =
new Gifts("ArtsAndCrafts");
}
public class GraphicsAndDesign : Dropdown
{
//prevent external inheritance
private GraphicsAndDesign(string value) : base(value) { }
public static readonly Dropdown CartoonsAndCaricatures =
new GraphicsAndDesign("CartoonsAndCaricatures");
public static readonly Dropdown LogoDesign =
new GraphicsAndDesign("LogoDesign");
public static readonly Dropdown Illustration =
new GraphicsAndDesign("Illustration");
}
public override string ToString()
{
return value;
}
}
In this case every single value is actually an instance of type Dropdown
, so you could have, say, a parameter to a method that accepts a Dropdown
instance. With enums there is no way to say, "I want to accept any of the enums declared in the Dropdown
class."
Here is some example usage:
public static void UseDropdown(Dropdown type)
{
if (type is Dropdown.Gifts)
{
if (type == Dropdown.Gifts.GreetingCards)
{
DoStuff();
}
}
else if (type is Dropdown.GraphicsAndDesign)
{
}
}
You could also have a parameter that accepts an object of type Gifts
or GraphicsAndDesign
, if you only want a sub-type to be valid in some context.
Sadly, using this solution there's no good way to switch
on a dropdown value; you have to just use if
/else if
chains to check the values.
The use of an instance string value may not be required (see the first revision for a version without it) but it can be very helpful to be able to have a meaningful string value (or other kind of value; you can associate an integer, a byte, or whatever with each enumeration value).
The Equals
and GetHashCode
implementations should be meaningful if left without being overridden.
You can implement IComparable
if the items should be logically ordered somehow, like real enums.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With