Alternar entre maiúsculas e minúsculas: posso usar um intervalo em vez de um número

86

Quero usar switch, mas tenho muitos casos, existe algum atalho? Até agora, a única solução que conheço e tentei é:

switch (number)
{
case 1: something; break;
case 2: other thing; break;
...
case 9: .........; break;
}

O que espero ser capaz de fazer é algo como:

switch (number)
{
case (1 to 4): do the same for all of them; break;
case (5 to 9): again, same thing for these numbers; break;
}
user3022162
fonte
1
Você pode usar if-else para esse cenário
Satpal

Respostas:

226

Um pouco tarde para o jogo para esta questão, mas nas recentes alterações introduzidas no C # 7 (disponível por padrão no Visual Studio 2017 / .NET Framework 4.6.2), a alternância baseada em intervalo agora é possível com a switchinstrução.

Exemplo:

int i = 63;

switch (i)
{
    case int n when (n >= 100):
        Console.WriteLine($"I am 100 or above: {n}");
        break;

    case int n when (n < 100 && n >= 50 ):
        Console.WriteLine($"I am between 99 and 50: {n}");
        break;

    case int n when (n < 50):
        Console.WriteLine($"I am less than 50: {n}");
        break;
}

Notas:

  • Os parênteses (e )não são necessários na whencondição, mas são usados ​​neste exemplo para destacar a (s) comparação (ões).
  • vartambém pode ser usado no lugar de int. Por exemplo: case var n when n >= 100:.
Steve Gomez
fonte
10
Você senhor, é meu heroi. Eu queria enfatizar isso com algum palavrão, mas não. :)
Gawie Greef
2
A condição (e )ao redor whensão desnecessários. Ou seja, case int n when n >= 100:também funciona.
Uwe Keim
6
Até varfunciona: ou seja case var n when n >= 100:.
Uwe Keim
9
@JamesKo Acho que está limpo e melhora a legibilidade em comparação com um monte de instruções if, especialmente se você tiver mais de 3-4 condições.
Sach de
1
Muito superior a um monte de declarações if, é muito mais limpo.
John Stock
44

Aqui está uma solução melhor e elegante para a definição do seu problema.

int mynumbercheck = 1000;
// Your number to be checked
var myswitch = new Dictionary <Func<int,bool>, Action>
            { 
             { x => x < 10 ,    () => //Do this!...  },  
             { x => x < 100 ,    () => //Do this!...  },
             { x => x < 1000 ,    () => //Do this!...  },
             { x => x < 10000 ,   () => //Do this!... } ,
             { x => x < 100000 ,  () => //Do this!... },
             { x => x < 1000000 ,  () => //Do this!... } 
            };

Agora, para chamar nosso switch condicional

   myswitch.First(sw => sw.Key(mynumbercheck)).Value();

Alternativo para Switch / ifElse

Akxaya
fonte
1
@Akxaya Eu ainda acho que o switch deve ser estendido em C #, mas isso parece fantástico e parece funcionar muito bem. Agradeço muito por compartilhar este exemplo. Obrigado
WonderWorker
Esta não é uma resposta clara para o alcance na questão de switch / case.
Pointer Null
13
O dicionário não armazena e retorna valores na ordem em que são adicionados. Isso funciona com o compilador da Microsoft, mas pode-se facilmente escrever um compilador compatível onde não funcione. Em vez disso, use List <KeyValuePair <Func <int, bool>, Action >>. Também esteja ciente de que há um custo para gerar a estrutura de dados e, portanto, provavelmente deve ser um membro somente leitura estático.
Nathan Phillips
@PointerNull: consulte o blog para obter o código necessário escrito nos comentários para referência futura
Akxaya
@NathanPhillips: obrigado por trazer isso à tona. Surpreendentemente, a coleção IList também seria uma alternativa. este foi apenas um exemplo que implementei com parâmetros complexos usando List <t>.
Akxaya de
13

Eu usaria operadores ternários para categorizar suas condições de switch.

Então...

switch( number > 9 ? "High" :
        number > 5 ? "Mid" :
        number > 1 ? "Low" : "Floor")
        {
              case "High":
                    do the thing;
                    break;
               case "Mid":
                    do the other thing;
                    break;
               case "Low":
                    do something else;
                    break;
               case "Floor":
                    do whatever;
                    break;
         }
graphicdivine
fonte
12

Para completar o tópico, aqui está a sintaxe com C # 8:

  var percent = price switch
  {
    var n when n >= 1000000 => 7f,
    var n when n >= 900000 => 7.1f,
    var n when n >= 800000 => 7.2f,
    _ => 0f // default value
  };

Se você deseja especificar os intervalos:

  var percent2 = price switch
  {
    var n when n >= 1000000 => 7f,
    var n when n < 1000000 && n >= 900000 => 7.1f,
    var n when n < 900000 && n >= 800000 => 7.2f,
    _ => 0f // default value
  };
A.Baudouin
fonte
8

If-else deve ser usado nesse caso, mas se ainda houver a necessidade de alternar por qualquer motivo, você pode fazer como abaixo, os primeiros casos sem interrupção se propagam até que a primeira interrupção seja encontrada. Como as respostas anteriores sugeriram, eu recomendo a troca if-else.

switch (number){
            case 1:
            case 2:
            case 3:
            case 4: //do something;
                    break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 9: //Do some other-thing;
                   break;
        }
Gayathri
fonte
8

Você poderia ter switchconstruído intervalos de "controle" usando-o em conjunto com um Listde seus limites.

List<int> bounds = new List<int>() {int.MinValue, 0, 4, 9, 17, 20, int.MaxValue };

switch (bounds.IndexOf(bounds.Last(x => x < j)))
{
    case 0: // <=0
        break;

    case 1: // >= 1 and <=4
        break;
    case 2: // >= 5 and <=9
        break;
    case 3: // >= 10 and <=17
        break;
    case 4: // >= 18 and <=20
        break;

    case 5: // >20
        break;
}

Com esta abordagem, os intervalos podem ter diferentes extensões.

user3598756
fonte
6

O intervalo é constante:

 int range = 5
 int newNumber = number / range;
 switch (newNumber)
 {
      case (0): //number 0 to 4
                break;
      case (1): //number 5 to 9
                break;
      case (2): //number 10 to 14
                break;
      default:  break;
 }

De outra forma:

  if else
Benba
fonte
3

Conforme mencionado, if-elseseria melhor neste caso, onde você estará lidando com um intervalo:

if(number >= 1 && number <= 4)
{
   //do something;
}
else if(number >= 5 && number <= 9)
{
   //do something else;
}
Henrik
fonte
2

Em .Net, apenas o Visual Basic permite intervalos em instruções switch, mas em C # não há sintaxe válida para isso.

Enfrentando seu problema específico em C #, eu o resolveria assim:

if(number >= 1 && number <= 9) // Guard statement
{
    if(number < 5)
    {
        // Case (1 to 4):

        //break;

    }
    else
    {
        // Case (5 to 9):

        //break;

    }

}
else
{
    // Default code goes here

    //break;

}

Para ilustrar isso melhor, imagine que você tem um valor percentual.

Usando seu problema como um modelo, você pode desejar que se pareça com:

switch (percentage)
{
    case (0 to 19):
        break;

    case (20 to 39):
        break;

    case (40 to 69):
        break;

    case (70 to 79):
        break;

    case (80 to 100):
        break;

    default:
        break;

}

No entanto, como o C # não permite essa sintaxe, aqui está uma solução que o C # permite:

if (percentage >= 0 && percentage <= 100) // Guard statement
{
    if (percentage >= 40)
    {
        if (percentage >= 80)
        {
            // Case (80% to 100%)

            //break;

        }
        else
        {
            if (percentage >= 70)
            {
                // Case (70% to 79%)

                //break;

            }
            else
            {
                // Case (40% to 69%)

                //break;

            }

        }

    }
    else
    {
        if (percentage >= 20)
        {
            // Case (20% to 39%)

            //break;

        }
        else
        {
            // Case (0% to 19%)

            //break;

        }

    }

}
else
{
    // Default code goes here

    //break;

}

Pode demorar um pouco para se acostumar, mas tudo bem assim que você conseguir.

Pessoalmente, gostaria de receber instruções switch para permitir intervalos.

O futuro das instruções de switch C #

Aqui estão algumas idéias que tive de como as instruções switch podem ser melhoradas:

Versão A

switch(value)
{
    case (x => x >= 1 && x <= 4):
    break;

    case (x => x >= 5 && x <= 9):
    break;

    default:
    break;

}

Versão B

switch(param1, param2, ...)
{
    case (param1 >= 1 && param1 <= 4):
    break;

    case (param1 >= 5 && param1 <= 9 || param2 != param1):
    break;

    default:
    break;

}
WonderWorker
fonte
1

Se você usa C / C ++, não há sintaxe de "intervalo". Você só pode listar todos os valores após cada segmento de "caso". Linguagem Ada ou Pascal suportam sintaxe de intervalo.

SliceSort
fonte
0

Em primeiro lugar, você deve especificar a linguagem de programação à qual está se referindo. Em segundo lugar, as switchinstruções são usadas adequadamente para conjuntos fechados de opções relacionadas à variável comutada, por exemplo, enumerações ou strings predefinidas. Para este caso, sugiro usar a boa e velha if-elseestrutura.

Andrei Nicusan
fonte
0

Através do switchcaso é impossível. Você pode usar instruções if aninhadas.

if(number>=1 && number<=4){
//Do something
}else if(number>=5 && number<=9){
//Do something
}
Joke_Sense10
fonte
Que tal o bom e velho em (number >= 1 && number <= 4)vez de verificar cada número? Como você escreveria entre 1 e 120 ? ;-)
DarkDust
Ah, e prestar atenção à =vs. ==.
DarkDust
-1

Se a pergunta foi sobre C (você não disse), então a resposta é não, mas : GCC e Clang (talvez outros) apoiar uma sintaxe gama , mas é não válida ISO C:

switch (number) {
    case 1 ... 4:
        // Do something.
        break;

    case 5 ... 9:
        // Do something else.
        break;
}

Certifique-se de ter um espaço antes e depois do ...ou você obterá um erro de sintaxe.

DarkDust
fonte
Pascal / delphi também faz isso. número de caso 1..4: fazer algo; etc.
Kell
A questão é sobre C #
SuB
@SuB: Eu sei. Eu adicionei a tag C # a esta pergunta depois que OP finalmente nos disse a qual idioma a pergunta se refere. Mas a resposta ainda pode ser útil para pessoas que vêm aqui por meio de um mecanismo de pesquisa, por isso não a excluí.
DarkDust
-1

No C #, os casos de switch são basicamente dicionários sobre o que fazer a seguir. Já que você não pode procurar um intervalo em um dicionário, o melhor que você pode fazer é o caso ... quando a declaração Steve Gomez mencionou.

user3406087
fonte
-3

Você pode usar instruções if-else com || operadores (ou-operator) como:

if(case1 == true || case2 == true || case3 == true)
   {
    Do this!... 
   }
else if(case4 == true || case5 == true || case6 == true)
   {
    Do this!... 
   }
else if(case7 == true || case8 == true || case9 == true)
   {
    Do this!... 
   }
Lukas Warsitz
fonte
Uau, isso é um pouco complicado para algo assim if (number >= 1 && number <= 4) { … } else if (number >= 5 && number <= 9) { … }, não acha?
DarkDust
Tudo bem, sim ... Ehm, mas se as caixas que deveriam fazer a mesma coisa não forem ordenadas, você precisa usar o '|| operador '...
Lukas Warsitz
Mas seu objetivo era verificar se um número está dentro de um intervalo, portanto, a ordem não importa (exceto para os intervalos verificados).
DarkDust
Não é uma falha , sua solução não está errada, apenas complicada ;-)
DarkDust
== true: face_palm: este é o comportamento padrão e para == false você pode usar not operator
Et7f3XIV