C# else if

Com if e else, o programa escolhe entre dois caminhos. Mas muitas decisões têm mais de dois: a nota vira conceito A, B, C ou D; a compra ganha 15%, 10%, 5% ou nenhum desconto; a temperatura é "frio", "agradável" ou "calor". Para isso existe o else if ("senão, se"): uma cadeia de perguntas, feitas uma de cada vez, em que só o primeiro caminho verdadeiro roda.

Você vai aprender
  • Como montar uma cadeia if … else if … else.
  • Por que só o primeiro caminho verdadeiro roda, e por que a ordem das condições importa.
  • Quando o else final é necessário (e o erro CS0165 sem ele).
  • A diferença entre else if e vários if separados.
  • Os erros de quem escreve elseif ou elif, ou põe o else no lugar errado.

Todos os programas desta aula rodaram com o .NET 10 (C# 14) na máquina fictícia da Ana, na pasta ~/cs, com dotnet run arquivo.cs.


A ideia: a fila de perguntas

Pense no porteiro de um parque de diversões que confere a altura das crianças, com uma lista de perguntas na mão:

  1. "Tem 1,40 m ou mais?" Se sim: "pode ir na montanha-russa". Acabou, ele não lê o resto.
  2. Se não: "tem 1,20 m ou mais?" Se sim: "pode ir no carrinho de bate-bate". Acabou.
  3. Se não: "tem 1,00 m ou mais?" Se sim: "pode ir no carrossel". Acabou.
  4. Se nenhuma deu certo: "só o parquinho, por enquanto".

Duas coisas importam aqui: ele para na primeira resposta "sim", e a lista está na ordem certa, da exigência maior para a menor. Uma cadeia de else if funciona exatamente assim.


1. A primeira cadeia

A escola da Ana transforma a nota (de 0 a 10) num conceito: 9 ou mais é A, 7 ou mais é B, 5 ou mais é C, e abaixo disso é D.

double nota = 7.5;
if (nota >= 9)
{
    Console.WriteLine($"Nota {nota}: conceito A");
}
else if (nota >= 7)
{
    Console.WriteLine($"Nota {nota}: conceito B");
}
else if (nota >= 5)
{
    Console.WriteLine($"Nota {nota}: conceito C");
}
else
{
    Console.WriteLine($"Nota {nota}: conceito D");
}
Console.WriteLine("Boletim gerado.");
$ dotnet run conceito.cs
Nota 7,5: conceito B         « 7,5 >= 9? não. 7,5 >= 7? sim: para aqui
Boletim gerado.
if (nota >= 9)
A primeira pergunta. Se for true, roda o bloco do A e pula todo o resto da cadeia.
else if (nota >= 7)
"Senão, se…": só é perguntado quando a anterior deu false. Por isso não precisa escrever nota < 9 && nota >= 7: se o programa chegou aqui, a nota já é menor que 9.
else if (nota >= 5)
Mais uma pergunta. Você pode pôr quantos else if quiser.
else
O último caminho, sem condição: roda quando todas as perguntas deram false. É opcional (seção 3).
Boletim gerado.
Depois da cadeia, o programa continua normalmente, seja qual for o caminho que rodou.

O 7,5 com vírgula na saída é a cultura brasileira da máquina da Ana: no código, o número se escreve com ponto (7.5); ao mostrar, o .NET usa a vírgula (aula float, double e decimal).

Como o programa caminha, para algumas notas:

Nota>= 9?>= 7?>= 5?Resultado
9,5sim(não pergunta)(não pergunta)A
7,5nãosim(não pergunta)B
5nãonãosimC
3nãonãonãoD (o else)

Missão: o programa diz "Calor" a partir de 30 graus e "Frio" até 15 graus, mas para 22 graus ele mostra "Frio", errado. Transforme o else num else if (temperatura <= 15) e acrescente um else final que mostre Agradável.

Agradável
int temperatura = 22;
if (temperatura >= 30)
{
    Console.WriteLine("Calor");
}
else
{
    Console.WriteLine("Frio");
}
int temperatura = 22;
if (temperatura >= 30)
{
    Console.WriteLine("Calor");
}
else if (temperatura <= 15)
{
    Console.WriteLine("Frio");
}
else
{
    Console.WriteLine("Agradável");
}

Depois de passar, troque o 22 por 35, por 10, por 30 e por 15. Os limites (30 e 15) caem em "Calor" e "Frio", por causa do >= e do <=.


2. A ordem importa

Como a cadeia para na primeira condição verdadeira, a ordem das perguntas muda o resultado. Veja o que acontece se a Ana escrever as faixas de baixo para cima:

double nota = 9.5;
if (nota >= 5)
{
    Console.WriteLine("Conceito C");
}
else if (nota >= 7)
{
    Console.WriteLine("Conceito B");
}
else if (nota >= 9)
{
    Console.WriteLine("Conceito A");
}
else
{
    Console.WriteLine("Conceito D");
}
$ dotnet run ordem.cs
Conceito C          « a melhor nota da turma ganhou C!

9,5 é maior ou igual a 5, então a primeira pergunta já deu true, e o programa nem chegou às outras. Com essa ordem, nenhuma nota a partir de 5 consegue B ou A: esses dois blocos ficaram impossíveis de alcançar. E o compilador não avisa nada, porque ele não sabe o que você queria.

Regra prática

Com >=, comece pelo maior limite e desça (9, 7, 5). Com < ou <=, comece pelo menor e suba (< 5, < 7, < 9). Se as faixas estiverem certas, cada pergunta "corta" um pedaço, e o que sobra vai para a próxima.


3. O else final é opcional

Sem o else no fim, pode acontecer de nenhum caminho rodar:

int temperatura = 22;
if (temperatura >= 30)
{
    Console.WriteLine("Calor");
}
else if (temperatura <= 15)
{
    Console.WriteLine("Frio");
}
Console.WriteLine("Fim da previsão.");
$ dotnet run semelse.cs
Fim da previsão.        « 22 não é calor nem frio: nenhum bloco rodou

Às vezes é isso mesmo que você quer (só avisar nos extremos). Mas quando a cadeia precisa sempre produzir um resultado, o else é obrigatório. O compilador sabe disso, e reclama quando uma variável pode ficar sem valor:

int nota = 8;
string conceito;
if (nota >= 9)
{
    conceito = "A";
}
else if (nota >= 7)
{
    conceito = "B";
}
Console.WriteLine($"Conceito {conceito}");
$ dotnet run semvalor.cs
/home/ana/cs/semvalor.cs(11,31): error CS0165: Uso de variável local não atribuída "conceito"

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

Se a nota fosse 4, nenhuma das duas perguntas daria true e conceito ficaria sem valor. O compilador olha todos os caminhos, não só a nota 8 de agora. Acrescente else { conceito = "C ou D"; } e o erro some: agora todo caminho dá um valor.


4. else if não é uma palavra nova

Uma curiosidade que ajuda a entender: o C# não tem uma instrução else if. É só um else cujo bloco é outro if. A cadeia da seção 1 é exatamente este programa, escrito com ifs "um dentro do outro":

double nota = 7.5;
if (nota >= 9)
{
    Console.WriteLine("Conceito A");
}
else
{
    if (nota >= 7)
    {
        Console.WriteLine("Conceito B");
    }
    else
    {
        if (nota >= 5)
        {
            Console.WriteLine("Conceito C");
        }
        else
        {
            Console.WriteLine("Conceito D");
        }
    }
}
$ dotnet run aninhado.cs
Conceito B

Mesmo resultado, mas o código vai "entortando" para a direita a cada faixa. Escrever else if numa linha só é a forma de manter a cadeia reta e fácil de ler. É por isso que a regra "chaves sempre" da aula anterior tem uma única exceção aceita por todo mundo: entre o else e o if, não vão chaves.


5. Faixas com &&

Às vezes fica mais claro escrever a faixa inteira, com && ("e"). O cinema da Ana cobra meia-entrada de crianças com menos de 12 anos e de quem tem 60 ou mais:

int idade = 35;
if (idade < 12)
{
    Console.WriteLine("Criança: meia-entrada");
}
else if (idade >= 12 && idade < 60)
{
    Console.WriteLine("Inteira");
}
else
{
    Console.WriteLine("60+: meia-entrada");
}
$ dotnet run faixa.cs
Inteira

O idade >= 12 é redundante: se o programa chegou ao else if, a idade já não é menor que 12. Funciona igual com ou sem ele. Algumas pessoas preferem escrever a faixa completa porque ela se explica sozinha; outras preferem a forma curta. As duas estão certas.


6. else if ou vários if?

Parece a mesma coisa escrever três if separados, mas não é. Cada if separado é uma pergunta nova, feita sempre, e mais de um bloco pode rodar:

double nota = 9.5;
if (nota >= 9)
{
    Console.WriteLine("Conceito A");
}
if (nota >= 7)
{
    Console.WriteLine("Conceito B");
}
if (nota >= 5)
{
    Console.WriteLine("Conceito C");
}
$ dotnet run separados.cs
Conceito A          « 9,5 >= 9
Conceito B          « 9,5 >= 7 também
Conceito C          « e 9,5 >= 5 também: três conceitos para uma nota!
Cadeia if / else ifVários if separados
Quantos blocos rodamNo máximo um (exatamente um, se tiver else)Zero, um ou vários
Quando usarAs opções se excluem: um conceito, uma faixa de descontoAs perguntas são independentes: "tem ovos?", "tem leite?", "tem pão?" (cada resposta gera um aviso)

Formas diferentes + qual usar

SituaçãoUse
Dois caminhosif / else (if e else)
Três ou mais caminhos com faixas (>=, <) ou condições diferentesif / else if / else (esta aula)
Vários caminhos que comparam a mesma variável com valores exatos (1, 2, 3; "pix", "cartão")switch
Escolher um valor por faixas, numa expressãoExpressões switch (nota switch { >= 9 => "A", … })

Quando dá errado

elseif ou elif: error CS1002: ; esperado
$ cat elseif.cs
int nota = 8;
if (nota >= 9)
{
    Console.WriteLine("A");
}
elseif (nota >= 7)
{
    Console.WriteLine("B");
}
$ dotnet run elseif.cs
/home/ana/cs/elseif.cs(6,19): error CS1002: ; esperado

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: em C#, são duas palavras: else if. Grudadas, elseif vira um nome qualquer, e elseif (nota >= 7) parece a chamada de um método chamado elseif. Uma chamada termina com ;, e o compilador reclama que o ; faltou no fim da linha 6 (coluna 19). Com o elif do Python, a mesma coisa: elif.cs(6,17): error CS1002: ; esperado.

O compilador para nesse erro de sintaxe e nem chega a procurar o outro problema (o nome elseif não existe). O editor do guia faz igual e mostra só o mesmo CS1002.

Como consertar: else if (nota >= 7), com espaço. (Também existe #elif em C#, mas é outra coisa: uma diretiva do pré-processador, que você não vai usar agora.)

error CS8641: 'else' não pode iniciar uma instrução.
$ cat elseantes.cs
int nota = 8;
if (nota >= 9)
{
    Console.WriteLine("A");
}
else
{
    Console.WriteLine("C");
}
else if (nota >= 7)
{
    Console.WriteLine("B");
}
$ dotnet run elseantes.cs
/home/ana/cs/elseantes.cs(9,2): error CS8641: 'else' não pode iniciar uma instrução.
/home/ana/cs/elseantes.cs(9,2): error CS1003: Erro de sintaxe, "(" esperado
/home/ana/cs/elseantes.cs(9,2): error CS1525: Termo de expressão inválido "else"
/home/ana/cs/elseantes.cs(9,2): error CS1026: ) esperado
/home/ana/cs/elseantes.cs(9,2): error CS1002: ; esperado

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: o else sem condição fecha a cadeia. Depois dele, a cadeia acabou, e o else if seguinte ficou sem if para se pendurar. Os quatro erros depois do primeiro são consequência dele.

Como consertar: o else sozinho vai sempre por último. Mova o else if para antes dele.

error CS0165: Uso de variável local não atribuída depois de uma cadeia

O que significa: a cadeia não tem else, então existe um caminho em que a variável não recebe valor.

Como consertar: acrescente o else final dando um valor, ou dê um valor inicial na declaração.

O programa compila, mas escolhe o caminho errado

O que significa: quase sempre, a ordem das condições (seção 2) ou um > no lugar de >= nos limites. O compilador não tem como saber.

Como consertar: teste o programa com os valores dos limites (9, 7, 5) e com um valor de cada faixa. Se as faixas usam >=, confira se elas estão do maior para o menor.


Referência rápida

EstruturaO que faz
if (c1) { A } else if (c2) { B } else { C }Roda A se c1; senão, B se c2; senão, C. Exatamente um dos três.
if (c1) { A } else if (c2) { B }Sem else: pode não rodar nenhum.
Ordem das faixas com >=Do maior limite para o menor.
Ordem das faixas com <Do menor limite para o maior.
else sozinhoSempre o último da cadeia.
elseif, elifNão existem em C# (CS1002). Escreva else if.

Exercícios

1. Senão, se

Complete com as duas palavras que continuam a cadeia:

if (x > 0) { Console.WriteLine("positivo"); } (x < 0) { Console.WriteLine("negativo"); } else { Console.WriteLine("zero"); }

2. O que aparece?

Com int pontos = 70;, o que este código mostra?

if (pontos >= 90) { Console.WriteLine("Ouro"); }
else if (pontos >= 60) { Console.WriteLine("Prata"); }
else if (pontos >= 30) { Console.WriteLine("Bronze"); }
else { Console.WriteLine("Sem medalha"); }
Saída:

3. O último da cadeia

Qual palavra, sozinha e sem condição, fecha uma cadeia de else if?

4. Com int idade = 70;, o que mostra if (idade >= 18) { Console.WriteLine("Adulto"); } else if (idade >= 60) { Console.WriteLine("Idoso"); }?

5. Qual é a diferença entre uma cadeia if/else if e vários if separados?

6. O que o compilador responde a elif (x > 0)?

Missão final: o desconto progressivo

Missão: a lojinha da Ana dá desconto pelo valor da compra: 15% a partir de R$ 500, 10% a partir de R$ 200, 5% a partir de R$ 100 e nenhum desconto abaixo disso. Monte a cadeia de if / else if / else que dá o valor certo a desconto. (Repare que int desconto; está sem valor: se faltar o else, você vai ver o CS0165.) Com a compra de 250, a saída deve ser:

Desconto: 10%
Total: R$ 225,00
decimal compra = 250m;
int desconto;

// escreva a cadeia aqui

decimal total = compra - compra * desconto / 100;
Console.WriteLine($"Desconto: {desconto}%");
Console.WriteLine($"Total: R$ {total:N2}");
decimal compra = 250m;
int desconto;

if (compra >= 500m)
{
    desconto = 15;
}
else if (compra >= 200m)
{
    desconto = 10;
}
else if (compra >= 100m)
{
    desconto = 5;
}
else
{
    desconto = 0;
}

decimal total = compra - compra * desconto / 100;
Console.WriteLine($"Desconto: {desconto}%");
Console.WriteLine($"Total: R$ {total:N2}");

Teste com os limites: 500 (15%), 499,99 (10%), 200 (10%), 100 (5%) e 99,90 (0%). Se algum der errado, confira a ordem da cadeia.


Resumo

  • if … else if … else escolhe entre vários caminhos. As perguntas são feitas em ordem, e só o primeiro caminho verdadeiro roda.
  • A ordem importa: com >=, do maior limite para o menor. O compilador não avisa quando a ordem está errada.
  • O else final é opcional e vai sempre por último. Sem ele, pode não rodar nada, e uma variável pode ficar sem valor (CS0165).
  • else if é um else cujo bloco é outro if; são duas palavras. elseif e elif não existem (CS1002).
  • Use a cadeia quando as opções se excluem; use ifs separados quando as perguntas são independentes.