Подтвердить что ты не робот

С# Строка переключателя, начиная с

Есть ли способ сделать условие case в инструкции switch, где вы говорите, что строка начинается с чего-то?

ех

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;
}

UPDATE Другие строки могут иметь разную длину.

а..

abczyv

DCS2.

QWERTY

как... к

4b9b3361

Ответ 1

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

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 как для исполняемого кода, так и для человека, который должен его поддерживать.

Изменить: добавлено, поскольку вы уже заявили, что они будут иметь разную длину. Вы могли бы сделать шаблон, который я упомянул, проверяя первые X-символы, а затем следующие Y-символы и т.д., Но если нет шаблона, в котором большая часть строк имеет одинаковую длину, это будет неэффективным и ужасным для поддержания (классический случай преждевременной пессимизации).

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

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

Цепочка if-else может работать очень хорошо, либо с помощью сравнения строк, либо с регулярными выражениями (последняя, ​​если у вас есть сравнения, более сложные, чем префикс-матчи до сих пор, что, вероятно, было бы проще и быстрее, я упоминание reg-ex только потому, что они иногда хорошо работают с более общими случаями такого рода шаблонов).

Если вы идете на if-elses, попробуйте рассмотреть, какие случаи будут происходить чаще всего, и сделайте эти тесты до тех, которые для менее распространенных случаев (хотя, конечно, если "начинается с abcd", это случай, чтобы посмотреть потому что его нужно было бы проверить до того, как "начнется с abc" ).

Ответ 2

Короткий ответ: Нет.

Оператор switch принимает выражение, которое оценивается только один раз. На основе результата выполняется другой фрагмент кода.

И что? = > String.StartsWith является функцией. Вместе с заданным параметром это выражение. Однако для вашего случая вам нужно передать другой параметр для каждого случая, поэтому его нельзя оценить только один раз.

Длинный ответ # 1 был предоставлен другими.

Длинный ответ # 2:

В зависимости от того, чего вы пытаетесь достичь, вас может заинтересовать Command Pattern/Шаблон цепочки ответственности. Применительно к вашему делу каждый фрагмент кода будет представлен реализацией команды. В дополнение к методу execute, команда может предоставить логический метод Accept, который проверяет, начинается ли заданная строка с соответствующим параметром.

Преимущество: вместо жесткого закодированного оператора switch, hardcoded 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");
    }
}    

Ответ 3

Если все случаи имеют одинаковую длину, вы можете использовать switch (mystring.SubString(0,Math.Min(len, mystring.Length))).
Другой вариант - иметь функцию, которая вернет categoryId на основе строки и включит идентификатор.

Ответ 4

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

switch(GetStringHeader(s))
{
    case StringHeader.ABC: ...
    case StringHeader.QWERTY: ...
    ...
}

StringHeader GetStringHeader(string s)
{
    if (s.StartsWith("ABC")) return StringHeader.ABC;
    ...
}

enum StringHeader { ABC, QWERTY, ... }

Ответ 5

В дополнение к ответу подстроки вы можете сделать это как mystring.SubString(0,3) и проверить регистр case, если его "abc".

Но перед оператором switch вам нужно убедиться, что ваш мистик по крайней мере 3 дюйма.

Ответ 6

Попробуйте это и сообщите мне, если он работает, надеюсь, что он вам поможет:

string value = Convert.ToString(Console.ReadLine());

Switch(value)
{
    Case "abc":

    break;

    default:

    break;
}