Mi sono imbattuto in un problema ricorrente in alcuni dei miei progetti recenti in cui mi trovo a usare enumerazioni per rappresentare stato, o tipo, o qualcos'altro, e ho bisogno di verificare alcune condizioni. Alcune di queste condizioni si estendono su enumerazioni multiple, quindi finisco con un carico di logica in switch
e if
blocchi, che non mi piacciono. Questo è un problema particolare quando devi lanciare le cose da e verso l'enumerazione, come quando l'enum viene usato per controllare un int che stai ricevendo da una richiesta web o da un calcolo.
C'è qualcosa in C ++ o C # che può essere usato come enum annidato? Qualcosa del genere:
enum Animal
{
Mammal
{
Cat,
Dog,
Bear
},
Bird
{
Pigeon,
Hawk,
Ostrich
},
Fish
{
Goldfish,
Trout,
Shark
},
Platypus //srsly what is that thing
};
Ovviamente, può o non può essere dichiarato in questo modo, ma tu hai l'idea. Il punto è che nel codice potresti usarlo come Animal thisAnimal = Animal.Mammal.Cat
e successivamente controllare if (thisAnimal.IsMember(Animal.Mammal))
o qualcosa del genere.
Ho visto l'EnumSet di Java, e le ho trovate piuttosto utili, ma non penso che corrispondano esattamente alla funzionalità che sto cercando. Per questo esempio, dovresti dichiarare un enum con tutti gli animali a un livello, e poi aggiungerli tutti ai set pertinenti. Ciò significherebbe che quando si utilizza l'enum originale, cose di livello superiore come Mammal
o Invertebrate
apparirebbero sullo stesso "livello" come qualcosa di molto specifico come African Swallow
, il che implicherebbe che fossero (in una certa misura) intercambiabile, che non è vero. In teoria, una struttura nidificata come sopra potrebbe consentire di specificare il livello di "specificità" necessario, quindi potresti ottenere questo:
enum Animal::Kingdom.Order.Family.Genus.Species
{ /*stuff*/ }
Organism::Kingdom.Phylum.Class.Order.Family thisThing;
thisThing = Animalia.Cordata; //compiler error
thisThing = Animalia.Chordata.Aves.Passeri.Hirundinidae; //compiles OK
Esiste una struttura come questa ovunque? In caso contrario, come potrei costruirne uno per C ++ e / o C # e mantenerlo il più generico e riutilizzabile possibile?