Grouping of best practices

If you have an enumeration where values ​​can be naturally grouped into subsets. For example:

[Flags]
public enum Instrument
{
    Lute,
    Guitar,
    Flute,
    Drum
}
[Flags]
public enum InstrumentType
{
    Percussion,
    String,
    Wind,
}

      

there are many ways to do this:

1) To combine this data into a separate Enum?

[Flags]
public enum ValidInstrument
{
    Lute= Instrument.Lute| InstrumentType.String,
    Guitar = Instrument.Guitar | InstrumentType.String,
    Flute = Instrument.Flute | InstrumentType.Wind,
    Drum = Instrument.Drum | InstrumentType.Percussion,
}

      

(assuming matching and non-overlapping values ​​are used between enums) which will allow you to do

(ValidInstrument | InstrumentType.String) == InstrumentType.String

      

to determine if a tool is a string or not

2) create some kind of display structure that does the same?

public static InstrumentType GetInstrumentType(Instrument inst)
{
    switch(inst)
    {
    case Instrument.Lute:
    case Instrument.Guitar:
        return InstrumentType.String
    //etc.
    }
}

      

3) Attributes?

public enum Instrument
{
    [InstrumentType(InstrumentType.String)]
    Lute,
    [InstrumentType(InstrumentType.String)]
    Guitar,
    [InstrumentType(InstrumentType.Wind)]
    Flute,
    [InstrumentType(InstrumentType.Percussion)]
    Drum
}

      

4) in a separate class?

public class ValidInstrument
{
public InstrumentType Type{get;set;}
public Instrument Instrument{get;set;}
}

      

with static aggregate

which of these methods is better or if it depends on the situation, what factors should influence the choice

+3


source to share


3 answers


Once you start talking about the relationship between things, it seems like you are talking about inheritance. The best practice would be to think of this as a class structure.

class Instrument
{
    void Play();
}

class StringedInstrument : Instrument
{
    void Strum();
}

class Guitar : StringedInstrument
{
}

      

With factory classes / methods and a few other design patterns, you should be able to handle the same things, and enumeration allows you, but also many others that you will never be able to handle with enumeration.



If you want to find all the band members who play the stringed instrument, you just get all the members where their instrument will be the "stringed instrument". This should be done in C # with a call Type.IsSubclassOf()

.

If a developer creates a class Flute

that inherits from StringedInstrument

, like in your comment above, you should start that developer! :) If you are talking about assigning an object to an Flute

instance StringedInstrument

, that will be prevented by C # because the cast is invalid. You can drop Flute

before WindInstrument

or Instrument

, but never StringedInstrument

if the developer wrongly inherits from the wrong tool type.

+1


source


Since it [Flags]

indicates that values enum

can be stored as bits, using comments for grouping rather than individual data structures is one way to balance potential readability with potential performance ... and why use [Flags]

, but for performance reasons?



+1


source


If you are just trying to manage a simple link then

Dictionary<Instrument, InstrumentType>

      

If you need strict adherence, then Inheritance

public class Guitar : StringInsturment 

      

I get that it can have an enum hierarchy, but I just don't understand what real life solution it solves. So the guitar has a description of String. By the time you wrap up some code to do something with it, you would be better off with class inheritance.

+1


source







All Articles