C# 有没有办法简化这个开关箱?
正如标题所说,我想简化switch case语句。我目前在我的switch case语句中有以下内容:C# 有没有办法简化这个开关箱?,c#,switch-statement,refactoring,C#,Switch Statement,Refactoring,正如标题所说,我想简化switch case语句。我目前在我的switch case语句中有以下内容: switch(someEnum) { case EnumType.A: SomeMethodSpecificToA(); AMethodIShouldCallOnAllVowels(); break; case EnumType.B: case EnumType.C: case EnumType.D: SomeMethodSpecificToTheseThree
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
语句链接起来,使它们执行相同的操作,但我不知道如何使两个字母执行两个独立的操作,然后对所有元音(或所有辅音)执行第二个语句。在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()
}
}
有没有一种方法不使用两个switch语句就可以做到这一点?这似乎是多余的,因为我已经打开了该变量。转到下一个案例是“转到案例2;”。
我还认为这是一个相关的问题:
[转到下一个案例是“转到案例2;”。
我还认为这是一个相关的问题:
[当我必须了解执行case
A
时会发生什么情况时,我不想向下滚动整个开关来确定A
是否多次发生
重构后,你真的得到了一个更好的可维护程序吗?KISS的解决方案难道不是在
a
标签后对“a的所有内容”进行分组吗?当我必须了解执行casea
时会发生什么时,我不想向下滚动整个开关来确定a
是否会发生更多不止一次
重构后,你真的得到了一个更好的可维护程序吗?KISS解决方案难道不是在
a
标签后分组“a的所有内容”吗?我只需将案例限制在特定()的,并在开关块之后放置一个简单的if-else:
if IsVowel
AMethodIShouldCallOnAllVowels();
else
AMethodIShouldCallOnAllConsonants();
还可以查看(但在这种情况下可能没有用处)。我只需将案例
限制为特定()的
,然后在开关块
之后放置一个简单的if-else:
if IsVowel
AMethodIShouldCallOnAllVowels();
else
AMethodIShouldCallOnAllConsonants();
还可以查看(但在这种情况下可能没有用处)
有没有一种方法不使用两个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();
}
<>上述重构只是一组封闭的值来模拟枚举的一种选择。策略或访问者模式也可能是有用的。
有没有一种方法不使用两个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();
}
<>上述重构只是一组封闭的值来模拟枚举的一种选择。策略或访问者模式也可能是有用的。由于构造的例子,很难想出比这个更好的答案。你有一些特定于某个字母的逻辑——属于一个开关/CAS。e、 你有额外的逻辑,这取决于字母是否是元音;这应该在开关块之外处理。由于人为的例子,很难想出比这个更好的答案。你有一些特定于某些字母的逻辑,这些字母属于开关/大小写。你有额外的逻辑,这取决于关于字母是否是元音;这应该在开关块之外处理。