Есть ли способ пролистать несколько операторов без case value:
повторения?
Я знаю, что это работает:
switch (value)
{
case 1:
case 2:
case 3:
// Do some stuff
break;
case 4:
case 5:
case 6:
// Do some different stuff
break;
default:
// Default stuff
break;
}
но я хотел бы сделать что-то вроде этого:
switch (value)
{
case 1,2,3:
// Do something
break;
case 4,5,6:
// Do something
break;
default:
// Do the Default
break;
}
Это синтаксис, о котором я думаю из другого языка, или я что-то упустил?
,
и тот, который не используется ни в каком другом языке c-style. Это показалось бы мне намного грязнее.Ответы:
В C ++ и C # нет синтаксиса для второго метода, который вы упомянули.
Нет ничего плохого в вашем первом методе. Однако, если у вас очень большие диапазоны, просто используйте серию операторов if.
источник
Я думаю, на это уже ответили. Тем не менее, я думаю, что вы все еще можете смешать оба варианта синтаксически лучше, выполнив:
источник
Этот синтаксис взят из выражения Visual Basic Select ... Case :
Вы не можете использовать этот синтаксис в C #. Вместо этого вы должны использовать синтаксис из вашего первого примера.
источник
В C # 7 (доступно по умолчанию в Visual Studio 2017 / .NET Framework 4.6.2) переключение на основе диапазона теперь возможно с помощью оператора switch и поможет решить проблему OP.
Пример:
Ноты:
(
и)
не обязательны вwhen
условии, но используются в этом примере, чтобы выделить сравнение (я).var
может также использоваться вместоint
. Например:case var n when n >= 7:
.источник
Вы можете пропустить новую строку, которая дает вам:
но я считаю этот плохой стиль.
источник
В .NET Framework 3.5 есть диапазоны:
Enumerable.Range от MSDN
Вы можете использовать его с «Содержит» и оператором IF, так как, как кто-то сказал, оператор SWITCH использует оператор «==».
Вот пример:
Но я думаю, что мы можем повеселиться: поскольку вам не понадобятся возвращаемые значения, а это действие не принимает параметров, вы можете легко использовать действия!
Старый пример с этим новым методом:
Поскольку вы передаете действия, а не значения, вы должны опустить скобки, это очень важно. Если вам нужна функция с аргументами, просто измените тип
Action
наAction<ParameterType>
. Если вам нужны возвращаемые значения, используйтеFunc<ParameterType, ReturnType>
.В C # 3.0 нет простого приложения для частичного применения, чтобы инкапсулировать тот факт, что параметр case такой же, но вы создали небольшой вспомогательный метод (немного многословно, хотя).
Вот пример того, как новые функциональные импортированные операторы ИМХО более мощные и элегантные, чем старые императивные.
источник
int start
иint count
. Ваши примеры не будут работать так, как они были написаны. Вы пишете это, как будто второй аргументint end
. Например -Enumerable.Range(11,20)
приведет к 20 числам, начинающимся с 11, а не к числам от 11 до 20.Enumerable.Range(11,20).Contains(c)
эквивалентноfor(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;
Если у вас есть большой выбор , что это займет много времени, а только с помощью>
и<
будет быстрыми и постоянная время.MySwitchWithEnumerable
возвращениеvoid
- слабый дизайн для этой ситуации. ПРИЧИНА: Вы преобразовалиif-else
в серию независимых операторов - которые скрывают намерение, а именно, что они являются взаимоисключающими,action
- выполняется только одно . Вместо того, чтобы вернутьсяbool
, с теломif (..) { action(); return true; } else return false;
Вызывающий сайт затем показывает намерение:if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));
. Это предпочтительнее. Тем не менее, это также больше не является значительным улучшением по сравнению с вашей первоначальной версией, для этого простого случая.Вот полное решение C # 7 ...
Это работает со строками тоже ...
источник
Код ниже не будет работать:
Единственный способ сделать это:
Код, который вы ищете, работает в Visual Basic, где вы легко можете поместить в диапазоны ... в качестве
none
опцииswitch
оператора илиif else
удобных блоков, я бы посоветовал в очень крайнем случае создать .dll с Visual Basic и импортировать обратно в ваш проект C #.Примечание: эквивалентный переключатель в Visual Basic есть
Select Case
.источник
Другим вариантом будет использование рутины. Если все случаи 1-3 выполняют одну и ту же логику, заключите эту логику в подпрограмму и вызовите ее для каждого случая. Я знаю, что на самом деле это не избавляет от операторов case, но реализует хороший стиль и сводит обслуживание к минимуму .....
[Edit] Добавлена альтернативная реализация для соответствия оригинальному вопросу ... [/ Edit]
Alt
источник
Одним из менее известных аспектов переключения в C # является то, что он опирается на оператор =, и, поскольку он может быть переопределен, вы можете получить что-то вроде этого:
источник
gcc реализует расширение языка C для поддержки последовательных диапазонов:
Редактировать : только что заметил тег C # в вопросе, так что, вероятно, gcc ответ не поможет.
источник
В C # 7 у нас теперь есть Pattern Matching, поэтому вы можете сделать что-то вроде:
источник
На самом деле мне тоже не нравится команда GOTO, но она есть в официальных материалах Microsoft, и здесь все допустимые синтаксисы.
Если конечная точка списка операторов секции switch достижима, возникает ошибка времени компиляции. Это известно как правило «не провалиться». Пример
допустимо, потому что ни одна секция коммутатора не имеет достижимой конечной точки. В отличие от C и C ++, выполнение раздела переключателя не может "провалиться" до следующего раздела переключателя, и пример
приводит к ошибке во время компиляции. Если за выполнением раздела переключателя следует выполнение другого раздела переключателя, необходимо использовать явный случай goto или оператор goto по умолчанию:
Допускается использование нескольких меток в секции переключателей. Пример
Я верю, что в данном конкретном случае GOTO можно использовать, и на самом деле это единственный путь к успеху.
Источник: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx
источник
goto
почти всегда можно избежать (хотя я не считаю его здесь «ужасным» - он выполняет определенную, структурированную роль). В вашем примере, поскольку вы обернули тела case в функции (что хорошо), case 0 может статьCaseZero(); CaseZeroOrOne(); break;
. Неgoto
требуетсяКажется, что была проделана огромная работа по поиску способов получить один из наименее используемых синтаксисов C #, чтобы как-то выглядеть лучше или работать лучше. Лично я считаю, что оператор switch редко стоит использовать. Я настоятельно рекомендую проанализировать, какие данные вы тестируете, и какие конечные результаты вы хотите получить.
Допустим, например, что вы хотите быстро проверить значения в известном диапазоне, чтобы увидеть, являются ли они простыми числами. Вы хотите, чтобы ваш код не занимался расточительными вычислениями, и вы можете найти список простых чисел в диапазоне, который вы хотите, онлайн. Вы можете использовать массивный оператор switch для сравнения каждого значения с известными простыми числами.
Или вы можете просто создать массив карт простых чисел и получить немедленные результаты:
Может быть, вы хотите увидеть, является ли символ в строке шестнадцатеричным. Вы можете использовать некрасивый и несколько большой оператор switch.
Или вы можете использовать либо регулярные выражения для проверки символа, либо использовать функцию IndexOf для поиска символа в строке известных шестнадцатеричных букв:
Допустим, вы хотите выполнить одно из 3 различных действий в зависимости от значения в диапазоне от 1 до 24. Я бы предложил использовать набор операторов IF. И если это стало слишком сложным (или числа были больше, например, 5 различных действий в зависимости от значения в диапазоне от 1 до 90), используйте перечисление для определения действий и создания карты массивов перечислений. Затем значение будет использоваться для индексации в карте массива и получения перечисления нужного вам действия. Затем используйте небольшой набор операторов IF или очень простой оператор switch для обработки полученного значения перечисления.
Кроме того, хорошая вещь о карте массива, которая преобразует диапазон значений в действия, состоит в том, что она может быть легко изменена кодом. С помощью проводного кода вы не можете легко изменить поведение во время выполнения, но с картой массива это легко.
источник
Чтобы добавить к разговору, используя .NET 4.6.2, я также смог сделать следующее. Я проверил код, и он работал на меня.
Вы также можете сделать несколько операторов «ИЛИ», как показано ниже:
Вы также можете проверить, соответствует ли оно значению в массиве:
источник
Если у вас очень много строк (или любого другого типа), делающих одно и то же, я рекомендую использовать список строк в сочетании со свойством string.Contains.
Так что если у вас есть большой оператор switch, например:
Вы могли бы хотеть заменить это
if
утверждением как это:Этот масштаб хорошо подходит для любого числа строковых падежей.
источник
Я думаю, что этот лучше в C # 7 или выше.
Вы также можете проверить Range в регистре переключателя C #: Switch case: могу ли я использовать диапазон вместо одного числа? Или если вы хотите понять основы переключения C #
источник
Для этого вы должны использовать оператор goto. Такие как:
источник
goto
. Хуже того, это совершенно ненужное использованиеgoto
, так как оригинальный синтаксис, указанный OP, работает. Вопрос заключался в том, существует ли более краткий способ дать альтернативные случаи. Как люди ответили за годы до того, как вы ответили , да, есть, если вы хотите поместить несколько дел в одну строкуcase 1: case 2:
, и если позволяет автоматический стиль редактора.