有没有办法简化这个switch-case?
Is there a way to simplify this switch-case?
如标题所说,我想简化一个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 语句就可以做到这一点的方法?这似乎是多余的,因为我已经打开了那个变量。
进入下一个案例是"goto Case 2;"。
我也相信这是一个相关的问题:
[Using `continue` keywoard in a switch nest inside a foreach loop
当我必须了解执行 case A
时会发生什么时,我不想向下滚动整个开关以查明 A
是否不止一次出现。
在重构之后,您真的得到了一个更好维护的程序吗? KISS 解决方案难道不是仅在 A
标签后分组 'all stuff for A' 吗?
我会简单地将 cases
限制为 Specific()'s
,并在 switch block
之后放置一个简单的 if-else:
if IsVowel
AMethodIShouldCallOnAllVowels();
else
AMethodIShouldCallOnAllConsonants();
另请查看 default:
(但在这种情况下可能没有用)。
Is there a way to do this without using 2 switch statements?
是的。使用 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();
根据实际代码中 'letters' 的复杂性,您可能会发现 类 比枚举更适合。这样做,您可以替换所有条件逻辑(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();
}
上述重构只是一组封闭值模拟枚举的一个选项。策略或访问者模式也可能有助于考虑。
如标题所说,我想简化一个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 语句就可以做到这一点的方法?这似乎是多余的,因为我已经打开了那个变量。
进入下一个案例是"goto Case 2;"。 我也相信这是一个相关的问题: [Using `continue` keywoard in a switch nest inside a foreach loop
当我必须了解执行 case A
时会发生什么时,我不想向下滚动整个开关以查明 A
是否不止一次出现。
在重构之后,您真的得到了一个更好维护的程序吗? KISS 解决方案难道不是仅在 A
标签后分组 'all stuff for A' 吗?
我会简单地将 cases
限制为 Specific()'s
,并在 switch block
之后放置一个简单的 if-else:
if IsVowel
AMethodIShouldCallOnAllVowels();
else
AMethodIShouldCallOnAllConsonants();
另请查看 default:
(但在这种情况下可能没有用)。
Is there a way to do this without using 2 switch statements?
是的。使用 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();
根据实际代码中 'letters' 的复杂性,您可能会发现 类 比枚举更适合。这样做,您可以替换所有条件逻辑(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();
}
上述重构只是一组封闭值模拟枚举的一个选项。策略或访问者模式也可能有助于考虑。