C# Switch-case строка, начинающаяся с
есть ли способ, чтобы сделать условие case в операторе switch, где вы говорите, если строка начинается с чего-то?
ex
Switch (mystring)
{
case("abc")://String begins with abc (abcd or abc1 or abcz or abc.. or abc will fall in this condition).
//Do Something
break;
default:
break;
}
обновление Другие строки могут быть разной длины.
abc..
abczyv
dcs2.
qwerty
as...k
6 ответов
Если бы вы знали, что длина условий, о которых вы заботитесь, будет одинаковой, вы могли бы:
switch(mystring.substring(0, Math.Min(3, mystring.Length))
{
case "abc":
//do something
break;
case "xyz":
//do something else
break;
default:
//do a different thing
break;
}
на Math.Min(3, mystring.Length)
существует так, что строка менее 3 символов не будет вызывать исключение для операции подстроки.
существуют расширения этого метода, чтобы соответствовать, например, куче строк 2-char и куче строк 3-char, где некоторые сопоставления 2-char затем следуют сравнения 3-char. Если у вас очень большой однако количество таких строк быстро становится менее эффективным, чем простая цепочка if-else как для запущенного кода, так и для человека, который должен его поддерживать.
Edit: добавлено, так как вы теперь заявили, что они будут разной длины. Вы можете сделать шаблон, о котором я упоминал, проверяя первые символы X, а затем следующие символы Y и так далее, но если нет шаблона, где большинство строк имеют одинаковую длину, это будет неэффективно и ужасно поддерживать (классический случай преждевременной pessimisation).
шаблон команды упоминается в другом ответе, поэтому я не буду давать подробностей об этом, так как это то, где вы сопоставляете шаблоны строк идентификаторам, но они являются опцией.
Я бы не менял цепочки if-else на команды или шаблоны отображения, чтобы получить переключатель эффективности иногда имеет над if-else, так как вы теряете больше в сравнениях для команды или получения шаблона ID. Я бы сделал это, если бы он сделал код более ясный.
цепочка if-else может работать довольно хорошо, либо со строковыми сравнениями, либо с регулярными выражениями (последнее, если у вас есть сравнения более сложные, чем префикс-совпадения до сих пор, что, вероятно, было бы проще и быстрее, я упоминаю reg-ex только потому, что они иногда хорошо работают с более общими случаями такого рода шаблона).
Если вы идете на if-elses, попробуйте рассмотреть, какие случаи будут происходить чаще всего, и сделать эти тесты это происходит раньше, чем для менее распространенных случаев (хотя, конечно, если "начинается с abcd" - это случай, который нужно искать, его нужно будет проверить перед "начинается с abc").
короткий ответ: Нет.
оператор switch принимает выражение, которое вычисляется только один раз. На основе результата выполняется другой фрагмент кода.
ну и что? => Строка.StartsWith-это функция. Вместе с заданным параметром это выражение. Однако для вашего случая вам нужно передать другой параметр для каждого случая, поэтому его нельзя оценить только один раз.
длинный ответ #1 был дан другими.
длинный ответ #2:
в зависимости от того, чего вы пытаетесь достичь, вас может заинтересовать Команда/цепь ответственности шаблон. Применительно к вашему случаю каждый фрагмент кода будет представлен реализацией команда. В дополнение к выполнить метод, команда может предоставить логическое принимать метод, который проверяет, начинается ли данная строка с соответствующей параметр.
преимущество: вместо вашего жестко закодированного оператора switch, жестко закодированных оценок StartsWith и жестко закодированных строк у вас будет намного больше гибкости.
пример, который вы дали в своем вопросе, будет выглядеть так:
var commandList = new List<Command>() { new MyABCCommand() };
foreach (Command c in commandList)
{
if (c.Accept(mystring))
{
c.Execute(mystring);
break;
}
}
class MyABCCommand : Command
{
override bool Accept(string mystring)
{
return mystring.StartsWith("abc");
}
}
Если все случаи имеют одинаковую длину, вы можете использоватьswitch (mystring.SubString(0,Math.Min(len, mystring.Length)))
.
Другой вариант - иметь функцию, которая будет возвращать categoryId на основе строки и переключаться на id.
если проблемный домен имеет какую-то концепцию заголовка строки, это может быть смоделировано как перечисление.
switch(GetStringHeader(s))
{
case StringHeader.ABC: ...
case StringHeader.QWERTY: ...
...
}
StringHeader GetStringHeader(string s)
{
if (s.StartsWith("ABC")) return StringHeader.ABC;
...
}
enum StringHeader { ABC, QWERTY, ... }
в дополнение к ответу подстроки, вы можете сделать это как mystring.Подстрока (0,3) и проверка в операторе case, если его "abc".
но перед инструкцией switch вам нужно убедиться, что ваша mystring по крайней мере 3 в длину.
попробуйте это и скажите мне, если это работает, надеюсь это поможет вам:
string value = Convert.ToString(Console.ReadLine());
Switch(value)
{
Case "abc":
break;
default:
break;
}