Is there a way to do this without using 2 switch statements?
Yes. Use if
statements.
EnumType[] Vowels = new [] {EnumType.A, EnumType.E, EnumType.I, EnumType.O, EnumType.U};
if (someEnum == EnumType.A)
SomeMethodSpecificToA();
if (new [] {EnumType.B, EnumType.C, EnumType.D}.Contains(someEnum))
SomeMethodSpecificToTheseThreeLetters();
if (someEnum == EnumType.E)
SomeMethodSpecificToE();
if (Vowels.Contains(someEnum))
AMethodIShouldCallOnAllVowels();
Depending on the complexity of the 'letters' in your actual code, you may find classes rather than enums better suited. In doing so, you can replace all conditional logic (if and switch statements). One refactoring option may be something like the below:
abstract class Letter
{
public char Value { get; private set; }
protected abstract void FrobInternal();
public void Frob()
{
FrobInternal();
// optionally code to be called for all letters
}
// private constructor limits inheritance to nested classes
private Letter(char value) { Value = value; }
class Vowel : Letter
{
public Vowel(char letter) : base(letter) { }
sealed protected override void FrobInternal()
{
FrobVowel();
AMethodIShouldCallOnAllVowels();
}
protected virtual void FrobVowel() { }
private void AMethodIShouldCallOnAllVowels()
{
// Implementation...
}
}
class Consonant : Letter
{
public Consonant(char letter) : base(letter) { }
sealed protected override void FrobInternal()
{
FrobConsonant();
AMethodIShouldCallOnAllConsanants();
}
protected virtual void FrobConsonant() { }
private void AMethodIShouldCallOnAllConsanants()
{
// Implementation...
}
}
class ConsonantBCD : Consonant
{
public ConsonantBCD(char letter) : base(letter) { }
protected override void FrobConsonant()
{
// Special implemenation for B, C, D
}
}
class LetterA : Vowel
{
public LetterA() : base('A') { }
protected override void FrobVowel()
{
// Special implementation for A
}
}
class LetterE : Vowel
{
public LetterE() : base('E') { }
protected override void FrobVowel()
{
// Special implementation for E
}
}
// use public readonly fields to replicate Enum functionality
public static readonly Letter A = new LetterA();
public static readonly Letter B = new ConsonantBCD('B');
public static readonly Letter C = new ConsonantBCD('C');
public static readonly Letter D = new ConsonantBCD('D');
public static readonly Letter E = new LetterE();
public static readonly Letter F = new Consonant('F');
// ...
public static readonly Letter Z = new Consonant('Z');
}
And then you could replace the prototype function above with simply:
void Test(Letter l) {
l.Frob();
}
The above refactoring is merely one option for a closed set of values to emulate an enumeration. The strategy or visitor patterns may also be useful to consider.