Динамическая отправка метода в зависимости от значения переменной - PullRequest
3 голосов
/ 01 декабря 2009

Длинные характеристики переключателя часто осуждаются. Решение заключается в использовании полиморфизма. Однако что, если вещь, которую я включаю, не является кодом типа? Я хотел бы заменить оператор switch чем-то вроде этого ...

public void HandleString(string s = "Hello")
{
 ...
}

public void HandleString(string s = "Goodbye")
{
 ...
}

...
HandleString("Hello"); // results in the first method being called.

Это заменит следующее ...

string s = "Hello";

switch(s)
{
   case "Hello":
   ...
   break;
   case "Goodbye":
   ...
   break;
   default;
   break;
}

Есть идеи? Теоретически, я думаю, что вы могли бы полностью отказаться от операторов if / switch и просто вызывать методы, которые автоматически связаны на основе значения выражения.

Ответы [ 2 ]

16 голосов
/ 01 декабря 2009

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

Dictionary<string, Action<string>> actions =
    new Dictionary<string, Action<string>>()
    {
        { "Hello", HandleHello },
        { "Goodbye", HandleGoodbye }
    };

private static void HandleHello(string s) { ... }

private static void HandleGoodbye(string s) { ... }

...

actions[s](s);

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

1 голос
/ 01 декабря 2009

Существуют языки, которые реализуют такую ​​семантику. Мне хорошо знаком инструмент генерации компилятора Elegant от Phillips.

На таком языке простой факторный алгоритм может выглядеть так:

fact (value : Int) : Int
    conditions value < 0
{
    { "Illegal input value\n" } astype Message
    return 0
}

fact (value = 0) : Int
{
    return 0
}

fact (value = 1) : Int
{
    return 1
}

fact (value : Int) : Int
{
    return value * fact(value - 1);
}
...