Переключатель/Случай замены с Шаблоном

Пустой указатель имеет значение и отсутствие данных, которые являются им, неизвестно, не значение данных ничего. Для людей происхождения программирования очень легко перепутать это, потому что на языках типа C при использовании пустого указателя указателей действительно ничто.

Следовательно в первом случае 3 находится действительно в наборе (1,2,3, пустой указатель), таким образом верный возвращается

Во втором однако, можно уменьшить его до

, выбирают 'верный', где 3 не в (пустом указателе)

, Таким образом, ничто не возвращается, потому что синтаксический анализатор ничего не знает о наборе, с которым Вы сравниваете его - это не пустое множество, а неизвестный набор. Используя (1, 2, пустой указатель) не помогает, потому что эти (1,2) устанавливают, очевидно, ложь, но тогда Вы - and'ing, что против неизвестного, который неизвестен.

8
задан Chris 17 February 2011 в 01:48
поделиться

6 ответов

Компиляторы очень хороши в оптимизации переключателя / случая конструкции; CLR, скорее всего, превратит его в справочную таблицу или что-то подобное быстро, поэтому ручная прокрутка вашей собственной версии, такой как предлагает Хенк Холтерман, - это не то, что я рекомендовал бы. CLR может лучше, чем вы, выбрать лучший алгоритм.

Если это проблема элегантности или ремонтопригодности, и у вас есть несколько переключателей / случаев, разбросанных по одному и тому же классу, выполняющему аналогичные функции, тогда один способ улучшить его. состоит в том, чтобы инкапсулировать всю функциональность, относящуюся к одному «случаю», в его собственный экземпляр класса, например:

class MyOption
{
    public static readonly MyOption Alpha = new MyOption(1, 10, "Alpha Text");
    public static readonly MyOption Bravo = new MyOption(2, 100, "Bravo Text");
    public static readonly MyOption Charlie = new MyOption(3, 1000, "Charlie Text");
    // ... Other options ...
    public static readonly MyOption Default = new MyOption(0, 0, null);

    public MyOption(int id, int value, string text)
    {
        this.ID = id;
        this.Value = value;
        this.Text = text;
    }

    public int ID { get; private set; }
    public int Value { get; private set; }
    public string Text { get; private set; }
}

Затем в вашем классе / элементе управления / странице:

static MyOption GetOption(string optionName)
{
    switch (optionName)
    {
        case "ALPHA":
            return MyOption.Alpha;
        case "BRAVO":
            return MyOption.Bravo;
        case "CHARLIE":
            return MyOption.Charlie;
        // ... Other options ...
        default:
            return MyOption.Default;
    }
}

private MyOption GetOptionFromDropDown()
{
    string optionName = GetOptionNameFromDropDown();
    return GetOption(optionName);
}

private string GetOptionNameFromDropDown()
{
    // ... Your code ...
}

После этого вы можете начать перемешивать события и другие методы:

private void control1_SomeEvent(object sender, EventArgs e)
{
    MyOption option = GetOptionFromDropDown();
    DoSomething(option.ID);
}

private void control2_SomeEvent(object sender, EventArgs e)
{
    MyOption option = GetOptionFromDropDown();
    DoSomethingElse(option.Value);
}

Конечно, это полезный шаблон, только если у вас есть несколько этих переключателей / вариантов, которые вы хотите преобразовать в один. Если у вас только один переключатель / корпус, вы просто получите намного больше кода, так что оставьте его в покое!

Другие возможности для улучшения ремонтопригодности включают:

  • ] Изменение строки на тип Enum (преобразование optionName с помощью Enum.Parse);
  • Перемещение всего материала MyOption / GetOption в отдельный класс (если у вас есть несколько классов / элементов управления / страниц, которые все должны работать с одним набором of choices);
  • Добавьте делегат метода в класс MyOption, если вам действительно нужно вызвать другой метод для каждого;
  • Пусть ваш DropDownList или другой элемент управления хранят прямую ссылку на экземпляр MyOption, если это возможно.

Вот и все. Писать просто, это Его легко понять, его легко поддерживать, он сэкономит ваше время, если у вас много конструкций switch / case, и по-прежнему позволяет CLR выполнять наилучшую оптимизацию. Единственная цена - небольшой объем памяти, необходимый для хранения этих полей только для чтения.

11
ответ дан 5 December 2019 в 05:56
поделиться

Вы можете создать таблицу для преобразования строки в значение параметра .

var lookup = new Dictionary<string, ParaType> ()  
{
    { "ALPHA", a  },
    { "BETA", b },
    ....
};

ParaType para;
if (lookup.TryGetValue(option, out para))   // TryGetValue, on popular request
{       
   // do repeative code method here; with para
}
11
ответ дан 5 December 2019 в 05:56
поделиться

Ключ к этой проблеме - сделать так, чтобы объекты, хранящиеся в dropDownList, предоставляли параметр (напрямую или путем индексации в массиве). Затем оператор switch может быть полностью удален.

Если параметр является свойством объекта, который отображается в раскрывающемся списке, то это очень эффективно предоставит значение.

Если значения в раскрывающемся списке могут предоставить числовой индекс в массив значений параметров, тогда это превзойдет серию сравнений строк с точки зрения эффективности времени выполнения.

Любой из этих вариантов чище, короче и проще в обслуживании, чем включение строки.

2
ответ дан 5 December 2019 в 05:56
поделиться

Возможно, преобразование из параметра в параметр метода?

Это позволит вам отбросить оператор switch и просто передать методу преобразованный параметр.

1
ответ дан 5 December 2019 в 05:56
поделиться

Вероятно, это перебор для того, что вы делаете, но код может стать чище.

class AlphabetChar
{
    public virtual void DoSomething(){}
}

class Alpha : AlphabetChar {}
class Bravo : AlphabetChar {}
...

class AlphabetCharFactory
{
    public static AlphabetChar GetByName(string name)
    {
         switch (name.ToUpper())
         {
             case "ALPHA":
                   return new Alpha();

             ...

             default:
                  //google for "wiki null object"
                  return new NullAlphabetChar();
         }
    }
}

Тогда вызывающий код станет ...

string option = dropDownList.SelectedValue.ToString();

AlphabetChar alphabetChar = AlphabetCharFactory.GetByName(option);

alphabetChar.DoSomething();

Как я сказал, это излишество, если все, что вы делаете, это установка параметра (в основном установка свойства в базовом классе из дочернего класса). Но если ваша логика более сложна, это может быть для вас жизнеспособным вариантом.

0
ответ дан 5 December 2019 в 05:56
поделиться

Думаю, я бы переместил оператор switch в отдельную функцию, чтобы он возвращал значение параметра для каждого случая:

    private static string GetParameterForAllCases(string option)
    {
        switch (option.ToUpper())
        {
            case "ALPHA":
                return "ALPHA Parameter";
            case "BRAVO":
                return "BRAVO Parameter";
            case "CHARLIE":
                return "CHARLIE Parameter";
            case "DELTA":
                return "DELTA Parameter";
            default:
                return "Default Parameter";
        }
    }

Тогда вы можете просто вызвать свой рабочий метод один раз:

        string option = dropDownList.SelectedValue.ToString();

        WorkMethod(GetParameterForAllCases(option);

Если вы не хотите выполнять свой метод работы по причине по умолчанию, или если у вас более одного значения параметра, вы можете изменить метод GetParameter для использования выходных параметров:

    private static bool GetParameter(string option, out string value)
    {
        switch (option.ToUpper())
        {
            case "ALPHA":
                value = "ALPHA Parameter";
                return true;
            case "BRAVO":
                value = "BRAVO Parameter";
                return true;
            case "CHARLIE":
                value = "CHARLIE Parameter";
                return true;
            case "DELTA":
                value = "DELTA Parameter";
                return true;
            default:
                value = null;
                return false;
        }
    }

И вызвать его так:

        string option = dropDownList.SelectedValue.ToString();

        string value;
        if (GetParameter(option, out value))
            WorkMethod(value);
3
ответ дан 5 December 2019 в 05:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: