Expressões Switch em C# Explicadas: Um Guia Prático de Tim Corey
No mundo do desenvolvimento em C#, escrever código limpo e de fácil manutenção é um objetivo fundamental. Um recurso moderno do C# que auxilia na conquista desse objetivo é a expressão switch — uma alternativa compacta e poderosa à tradicional instrução switch. Embora muitas vezes negligenciadas, as expressões switch simplificam a lógica de ramificação complexa, especialmente ao lidar com padrões relacionais, correspondência de padrões e padrões constantes.
Para entender melhor como esse recurso funciona e como ele se compara às abordagens tradicionais, vamos analisar um vídeo explicativo de Tim Corey. Ao longo de seu vídeo sobre " Expressões Switch em C# ", Tim detalha o uso prático de expressões switch em C#, demonstrando como escrever um código melhor com menos linhas.
Vamos analisar a explicação prática de Tim, que começa com um exemplo de avaliação e avança para cenários mais complexos usando interfaces, padrões de tipo e avaliação de objetos.
Expressão tradicional if-else versus expressão switch
Tim começa com um aplicativo de console onde uma variável inteira chamada numberGrade armazena uma nota de prova, como 85. O objetivo é converter esse valor numérico de entrada em uma nota correspondente em forma de letra, como 'B'. Na maioria dos casos, os desenvolvedores usariam uma série de instruções if-else ou uma instrução switch, como esta:
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so on
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so on
Embora funcione, é muito prolixo. Por outro lado, as expressões switch em C# oferecem uma sintaxe mais limpa.
Escrevendo uma expressão switch para avaliação
Para demonstrar uma expressão switch, Tim reescreve a lógica acima usando o seguinte código:
string letterGrade = numberGrade switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
string letterGrade = numberGrade switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
Aqui, a palavra-chave switch é usada em um novo contexto — como uma expressão, não como uma declaração. Isso significa que ele avalia diretamente para um valor e pode ser atribuído a uma variável (como letterGrade).
Este formulário suporta padrões relacionais (por exemplo, >= 90) e usa o padrão de descarte (_) para lidar com o caso padrão, que é equivalente ao else final.
Tim observa que o compilador determina a correspondência em tempo de execução, verificando cada condição de cima para baixo e escolhendo o primeiro padrão que se encaixa na entrada.
Simplificando o código com expressões
Nas palavras de Tim, essa nova sintaxe "substitui uma grande quantidade de código". Em vez de repetir condições com else if, a expressão switch lida com tudo em uma estrutura clara e concisa. Isso simplifica o fluxo de controle, melhora a legibilidade e reduz a redundância na sua lógica.
Ele enfatiza que essa estrutura é especialmente útil ao mapear valores de entrada para saídas específicas — como notas, mensagens de status ou transformação de dados.
Utilizando a correspondência de padrões com tipos de objetos
Para explorar padrões de tipo e correspondência de padrões, Tim apresenta um cenário envolvendo uma interface IAnimal. Ele define três classes — Cachorro, Gato e Vaca — cada uma implementando a interface. Isso permite que ele crie uma lista de animais, cada um com propriedades diferentes.
interface IAnimal { }
record Dog(string Name) : IAnimal;
record Cat(string Title, string Name) : IAnimal;
record Cow(string Breed) : IAnimal;
interface IAnimal { }
record Dog(string Name) : IAnimal;
record Cat(string Title, string Name) : IAnimal;
record Cow(string Breed) : IAnimal;
Ele cria uma lista com várias instâncias de animais e demonstra como usar a correspondência de padrões de tipo para identificar o tipo de objeto e extrair os dados.
Switch Expression com Pattern Matching
Tim demonstra como o seguinte código utiliza instruções if:
if (a is Dog d)
message = $"Dog: {d.Name}";
else if (a is Cat c)
message = $"Cat: {c.Title} {c.Name}";
else if (a is Cow co)
message = $"Cow: {co.Breed}";
else
message = "Unknown animal";
if (a is Dog d)
message = $"Dog: {d.Name}";
else if (a is Cat c)
message = $"Cat: {c.Title} {c.Name}";
else if (a is Cow co)
message = $"Cow: {co.Breed}";
else
message = "Unknown animal";
Pode ser substituído por uma expressão switch muito mais compacta e legível:
string message = a switch
{
Dog d => $"Dog: {d.Name}",
Cat c => $"Cat: {c.Title} {c.Name}",
Cow co => $"Cow: {co.Breed}",
_ => "Unknown animal"
};
string message = a switch
{
Dog d => $"Dog: {d.Name}",
Cat c => $"Cat: {c.Title} {c.Name}",
Cow co => $"Cow: {co.Breed}",
_ => "Unknown animal"
};
Essa expressão verifica o tipo do objeto e aplica a saída correta com base no padrão encontrado. Se nenhuma correspondência for encontrada, o programa recorre a um resultado padrão usando o descarte _.
Essa funcionalidade aprimora a operação sem comprometer a clareza. O comportamento em tempo de execução permanece previsível e legível.
Guardas opcionais com a palavra-chave "quando"
Embora não demonstrado no exemplo de Tim, é importante notar que as expressões switch podem ser estendidas com a palavra-chave when para aplicar uma condição booleana opcional:
int score = 90;
string result = score switch
{
int s when s >= 90 && s <= 100 => "Excellent",
int s when s >= 75 => "Good",
_ => "Needs Improvement"
};
int score = 90;
string result = score switch
{
int s when s >= 90 && s <= 100 => "Excellent",
int s when s >= 75 => "Good",
_ => "Needs Improvement"
};
Aqui, a cláusula when permite a avaliação personalizada do argumento, usando expressões booleanas mais complexas.
Melhores Práticas e Considerações Finais
Tim enfatiza um conceito crucial: embora as expressões switch tornem seu código mais compacto, compacto nem sempre significa melhor. Às vezes, especialmente com lógica complexa ou entradas pouco claras, uma instrução switch tradicional ou um bloco if podem ser mais apropriados.
Você não precisa usar uma expressão switch em todos os casos — use a ferramenta certa para cada tarefa. Não se trata de entrar para o "culto da troca de casais", como Tim brinca. Trata-se de escrever código de fácil manutenção e compreensão para o seu sistema.
Resumo: Adicionando expressões switch à sua caixa de ferramentas de desenvolvedor
As expressões switch em C# oferecem uma maneira moderna e elegante de avaliar e retornar valores com base em padrões de entrada, usando uma combinação de padrões constantes, relacionais e de tipo. São ideais quando se deseja simplificar a lógica, reduzir o código repetitivo e melhorar a legibilidade.
Desde a classificação de números inteiros até a identificação de animais, os exemplos a seguir no vídeo de Tim Corey destacam seus usos práticos. Seja para criar uma função que calcule resultados, lidar com a entrada do usuário ou trabalhar com casos nulos e indefinidos, as expressões switch podem ajudar a economizar tempo, reduzir erros e tornar seu código mais fácil de gerenciar.
Como diz Tim, "São uma ferramenta muito útil para se ter à disposição, pois tornam o código mais simples e limpo, sem deixar de ser compreensível, ou até mais."
Se você busca melhorar a qualidade do seu código C# e acompanhar as inovações do .NET Core , não ignore as expressões switch. Experimente-os em seus projetos do Visual Studio e veja como sua lógica pode ficar muito mais limpa.
