簡體   English   中英

有沒有辦法簡化這種開關情況?

[英]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語句? 當我已經打開該變量時,這似乎很多余。

我只是將cases限制在Specific()'s ,並在switch block放置一個簡單的if-else:

if IsVowel
    AMethodIShouldCallOnAllVowels();
else
    AMethodIShouldCallOnAllConsonants();

還要檢查default:但在這種情況下可能沒有用)。

轉到下一個案例是“轉到案例2;”。 我也相信這是一個相關的問題:[ 在foreach循環內的開關嵌套中使用`continue` keywoard

有沒有一種方法,而無需使用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();
}

上面的重構僅僅是一組封閉值模擬枚舉的一個選項。 策略或訪客模式也可能有用。

當我必須了解執行情況A時會發生什么時,我不想向下滾動整個開關以查找是否發生了多次A

重構之后,您真的要進入一個更好維護的程序了嗎? KISS解決方案不是將“ A的所有內容”分組到A標簽之后嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM