就像标题所说,我想简化一个switch-case语句。我目前在我的switch-case声明中有这个:
switch(someEnum) {
case EnumType.A:
SomeMethodSpecificToA();
AMethodIShouldCallOnAllVowels();
break;
case EnumType.B:
case EnumType.C:
case EnumType.D:
SomeMethodSpecificToTheseThreeLetters();
AMethodIShouldCallOnAllConsonants();
break;
case EnumType.E:
SomeMethodSpecificToE();
AMethodIShouldCallOnAllVowels();
break;
// All other letters, also containing the vowels & consonants methods
}
所以我知道我可以链接多个case
语句以使它们做同样的事情,但我不知道我怎么能这样做,以便2个字母做2个单独的事情然后落到第二个声明,适用于所有元音(或所有辅音)。在Swift我会做这样的事情:
func test(someEnum: EnumType) {
switch someEnum {
case .A:
someMethodSpecificToA()
fallthrough
case .B, .C, .D:
someMethodSpecificToTheseThreeLetters()
fallthrough
case .E:
someMethodSpecificToE()
fallthrough
case .A, .E:
aMethodIShouldCallOnVowels()
case .B, .C, .D:
aMethodIShouldCallOnAllConsonants()
}
}
有没有办法在不使用2个switch语句的情况下执行此操作?这似乎是多余的,因为我已经打开了那个变量。
答案 0 :(得分:4)
答案 1 :(得分:1)
转到下一个案例是"转到案例2;"。 我也相信这是一个相关的问题: [Using `continue` keywoard in a switch nest inside a foreach loop
答案 2 :(得分:1)
有没有办法在不使用2个switch语句的情况下执行此操作?
是。使用if
语句。
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();
根据实际代码中“字母”的复杂程度,您可能会发现类而不是枚举更适合。这样做,您可以替换所有条件逻辑(if和switch语句)。一个重构选项可能如下所示:
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');
}
然后您可以简单地替换上面的原型函数:
void Test(Letter l) {
l.Frob();
}
上述重构只是一组封闭的值来模拟枚举的一个选项。策略或访客模式也可能有用。
答案 3 :(得分:0)
当我必须了解执行案例Arith
时会发生什么情况时,我不想向下滚动整个开关以查明A
是否多次出现。
在重构之后,你真的在一个更好的可维护程序中结束了吗? KISS解决方案不是仅仅在A
标签之后将“所有内容”组合在一起吗?