Минимизация количества операторов if / else if - PullRequest
0 голосов
/ 04 сентября 2018

Я сейчас программирую речевой инструмент в проекте в моем университете. Я получил совет сократить количество выражений if / else if, но я не могу думать о другом способе решения этого вопроса, кроме, возможно, switch / case.

Каждый голосовой вывод отличается, и сопрограммам нужны разные параметры в зависимости от типа поезда. Так что я не знаю, как это упростить. Существуют ли специальные методы / лучшие практики в C # для решения подобных проблем?

Приложение разработано в Unity с Microsoft Speech API

Значит, утверждения похожи на

if (spokenText.IndexOf("Ticket") > 0)
        // Voice Output

else if (spokenText.IndexOf("Wo") > 0)
    {
        if (spokenText.IndexOf("Bahn") > 0 || spokenText.IndexOf("Zug") > 0)
        {
            //Ask for Train
        }
        else if (spokenText.IndexOf("nächste") > 0 && (spokenText.IndexOf("RE") > 0 || spokenText.IndexOf("S-Bahn") > 0 || spokenText.IndexOf("ICE") > 0) || spokenText.IndexOf(" S ") > 0
            || spokenText.IndexOf("IC") > 0 || spokenText.IndexOf("EC") > 0)
        {

            if (spokenText.IndexOf("ICE") > 0)
            {
                //Start Coroutine
            }
            else if (spokenText.IndexOf("EC") > 0)
            {
               // Start Coroutine with different Parameter
            }
            else if (spokenText.IndexOf("IC") > 0)
            {
            //Start Coroutine with different Parameter
            }
        }
        else
            // Voice output
    }
    else if (spokenText.IndexOf("Wann") > 0)
    {
        if ((spokenText.IndexOf("Zug") > 0 || spokenText.IndexOf("Bahn") > 0) && spokenText.IndexOf("nächste") > 0 && spokenText.IndexOf("nach") > 0)
        {
            // Coroutine
        }
        else if (spokenText.IndexOf("Zug") > 0 || spokenText.IndexOf("Bahn") > 0)
        {
            // Voice output
        }

        else if (spokenText.IndexOf("nächste") > 0 && (spokenText.IndexOf("RE") > 0 || spokenText.IndexOf("S-Bahn") > 0 || spokenText.IndexOf("ICE") > 0) || spokenText.IndexOf(" S ") > 0
            || spokenText.IndexOf("IC") > 0 || spokenText.IndexOf("EC") > 0)
        {

            if (spokenText.IndexOf("ICE") > 0)
            {

               // Coroutine
            }
            else if (spokenText.IndexOf("EC") > 0)
            {
              //Coroutine
            }
            else if (spokenText.IndexOf("IC") > 0)
            {
              //Coroutine
            }
        }
        else
            //Voice Output

    }
    else if (spokenText.IndexOf("Barrierefrei") > 0 || spokenText.IndexOf("Aufzug") > 0 || spokenText.IndexOf("Rolltreppe") > 0)
    {
        //Coroutine
    }
    else {
        //Voice Output
    }
}

edit: сначала добавляется оператор if

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

У вас слишком много не связанных предметов в одной категории. Разделите параметры на небольшие группы, как показано ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        enum MODE
        {
            GERMAN, 
            TICKET,
            WANN, 
            WO,
        }
        enum COROUTINE
        {
            ICE,
            EC,
            IC,
            BARRIEREFREI,
            AUFZUG,
            ROLLTREPPE,
            ZUG,
            BAHN,
            NÄCHSTE
        }
        static void Main(string[] args)
        {
            MODE mode = MODE.TICKET;
            COROUTINE coroutine =   COROUTINE.IC;
            string language = "nächste";

            switch (mode)
            {
                case MODE.GERMAN :
                    switch (language)
                    {
                        case "Barrierefrei" :
                            Coroutine(COROUTINE.BARRIEREFREI);
                            break;
                        case "Aufzug":
                            Coroutine(COROUTINE.AUFZUG);
                            break;
                        case "Rolltreppe":
                            Coroutine(COROUTINE.ROLLTREPPE);
                            break;
                    }
                    break;
                case MODE.TICKET:
                    Voice();
                    break;
                case MODE.WANN:
                    switch (language)
                    {
                        case "Zug":
                            Coroutine(COROUTINE.ZUG);
                            break;
                        case "Bahn":
                            Coroutine(COROUTINE.BAHN);
                            break;
                        case "NÄCHSTE":
                            Coroutine(COROUTINE.NÄCHSTE);
                            break;
                        default :
                            Voice();
                            break;
                    }
                    break;
                case MODE.WO:
                    switch (coroutine)
                    {
                        case  COROUTINE.EC :
                            Coroutine(COROUTINE.EC);
                            break;
                        case COROUTINE.ICE:
                            Coroutine(COROUTINE.ICE);
                            break;
                        case COROUTINE.IC :
                            Coroutine(COROUTINE.IC);
                            break;
                        default :
                            Train();
                            break;
                    }
                    break;
                default :
                    Voice();
                    break;
            }
        }

        static void Coroutine(COROUTINE parameter)
        {
        }
        static void Voice()
        {
        }
        static void Train()
        {
        }

    }
}
0 голосов
/ 05 сентября 2018

Пара наблюдений. Ваш метод слишком длинный и поэтому подвержен ошибкам. Я следую личному правилу, чтобы иметь метод, который не требует прокрутки.

Во-вторых, число операторов if / else обычно соответствует паттерну стратегии .

SpokenTextStrategy (или Stragtegies) может быть похож на TicketStrategy, WoStrategy, WannStrategy.

Кроме того, вы можете заключить это в один метод: enum SomeTextCheck {ICE, EC, IC};

if (spokenText.IndexOf("ICE") > 0)
{
    // Coroutine
}

else if (spokenText.IndexOf("EC") > 0)
{
    //Coroutine
}

else if (spokenText.IndexOf("IC") > 0)
{
 //Coroutine
}
0 голосов
/ 05 сентября 2018

Неэффективно вызывать IndexOf для одной и той же строки столько раз. Вы можете разбить строку на токены и использовать Dictionary<string, Action> для вызова метода для каждого токена, что-то вроде этого:

class Program
{
    static void Main(string[] args)
    {
        var sc = new SomeClass();

        sc.ProcessTokens("aa bb");
    }
}

class SomeClass
{
    private Dictionary<string, Action> actions = new Dictionary<string, Action>();

    private int someContext = 0;

    public SomeClass()
    {
        actions["aa"] = DoA;
        actions["bb"] = DoB;
    }

    public void ProcessTokens(string tokens)
    {
        foreach (var token in tokens.Split(' '))
            actions[token]();
    }

    private void DoA()
    {
        someContext++;
        Console.Write("A" + someContext.ToString());
    }

    private void DoB()
    {
        someContext++;
        Console.Write("B" + someContext.ToString());
    }

Таким образом, вместо тысяч if-else-если у вас есть сотни методов, которые вы вызываете один за другим, и в одном и том же классе отслеживайте контекст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...