Когда использовать FOR-CASE (Foreach / switch в C #)? - PullRequest
1 голос
/ 02 декабря 2008

Я нашел то, что похоже на C # эквивалент FOR-CASE структуры в проекте, над которым я работаю:

foreach (string param in params.Split(';'))
{
    string[] parts = param.Split('=');
    string key = parts[0].Trim().ToLower();
    string value = parts[1].Trim();
    switch (key)
    {
        case "param1": this.param1 = value; break;
        case "param2": this.param2 = value; break;
        case "param3": this.param3 = value; break;
        case "param4": this.param4 = value; break;
        default: break;
    }
}

(Имена переменных изменены для защиты виновных.)

Как бы вы реализовали этот код?

Ответы [ 7 ]

6 голосов
/ 03 декабря 2008

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

Код в вопросе выглядит как то, что я мог бы сделать, если бы написал инструмент командной строки.

Я глуп, что не вижу, что не так с кодом в вопросе?

Альтернативой является использование отражения для заполнения переменных значения параметра. Я тоже так иногда делаю.

Кстати: однажды я написал программу на языке сценариев, в которой переключение было единственным механизмом управления потоком, а gosub / return отсутствовал. Код в моей программе был немного похож на тот, на который вы ссылались. Массивное переключение на своего рода переменную указателя инструкций, которая переназначается в конце каждого случая, и почти бесконечный цикл вокруг переключателя. Он сделал свою работу.

4 голосов
/ 03 декабря 2008

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

В противном случае, вы можете иметь 1 HashTable (возможно, добавьте индексатор C # как поворот) для хранения всех из них, и ваш цикл закончится так:

foreach (string param in params.Split(';'))
{
    string[] parts = param.Split('=');
    string key = parts[0].Trim().ToLower();
    string value = parts[1].Trim();
    MyHashTable[key] = value;
}

Проблема этого подхода в том, что у вас должен быть только 1 тип значения. Например, если ваш список параметров может содержать как строковые, так и int-типы, это усложняет код, особенно вам необходимо выполнить проверку ошибок, проверку и прочее.

Лично я бы придерживался того, что у вас уже есть.

3 голосов
/ 03 декабря 2008

Вы можете использовать отражение для этого:

Type t = this.GetType();
foreach (string param in params.Split(';'))
{    
    string[] parts = param.Split('=');    
    string key = parts[0].Trim().ToLower();    
    string value = parts[1].Trim();    

    t.GetProperty(key).SetValue(this, value, null);
}
2 голосов
/ 03 декабря 2008

Для чего бы то ни было, статья WTF была WTF, потому что ее внешний цикл был совершенно бесполезен, как отмечалось в статье, - это было так же просто и более просто, просто установить индексную переменную напрямую, чем зацикливать и тестировать это.

1 голос
/ 03 декабря 2008

Не уверен, что я тоже понимаю, но, похоже, ты усложняешь себя. Не изобретайте велосипед, используйте как можно больше классов BCL, эти классы доказали свою эффективность и сэкономили много времени. Похоже, вы могли бы реализовать его с помощью некоторого словаря <,> вместе с, как предположил Гуге, отражением.

0 голосов
/ 12 декабря 2008

Я действительно думаю, что код ОП в порядке. Он не идеален - могут быть более простые или более чистые способы сделать это, но он эффективно допускает удобочитаемые отображения между именами элементов / свойств и именами входных параметров. Он оставляет ваши свойства строго типизированными (в отличие от решений для хэш-карт и словарей, если у вашего класса только один тип для всех его свойств ...) и дает вам одно достаточно очевидное место для исправления или добавления сопоставлений.

0 голосов
/ 03 декабря 2008

Или регулярное выражение:

string parms = "param1=1;param2=2;param3=3";
string[] parmArr = parms.Split(';');        

string parm1 = Regex.Replace(parmArr[0], "param1=", "");
string parm2 = Regex.Replace(parmArr[1], "param2=", "");
string parm3 = Regex.Replace(parmArr[2], "param3=", "");
...