IRONSOFTWAREHOME
ATUALIZAÇÕES DO DESENVOLVEDOR

Expressões de correspondência de padrões em C# (Como funciona para desenvolvedores)

Curtis Chau
Curtis Chau
Updated: 21 de abril de 2026

A correspondência de padrões em C# é um recurso poderoso que foi introduzido no C# 7.0 e, desde então, expandido em versões subsequentes. Isso permite que os desenvolvedores escrevam um código mais conciso e expressivo ao lidar com instruções condicionais, verificação de tipos e desconstrução de objetos.

Expressões de correspondência de padrões oferecem uma maneira flexível e intuitiva de comparar valores com padrões e executar os blocos de código correspondentes. Neste artigo, exploraremos as complexidades das expressões de correspondência de padrões em C#, incluindo sintaxe, casos de uso e exemplos de código. Ao final do artigo, também exploraremos um pouco sobre a biblioteca IronPDF da Iron Software , que permite gerar documentos PDF dinamicamente em aplicações C#.

Benefits of Pattern Matching in C#

A correspondência de padrões em código C# apresenta uma série de vantagens:

  • Legibilidade aprimorada: o casamento de padrões simplifica a lógica condicional complexa, tornando seu código mais fácil de entender e seguir, tanto para você quanto para outros desenvolvedores.
  • Redução no número de linhas de código: Ao condensar instruções condicionais complexas em padrões concisos, o pattern matching ajuda a simplificar sua base de código, resultando em menos linhas de código e uma implementação mais sucinta.
  • Melhoria na manutenção: A clareza proporcionada pela correspondência de padrões facilita a manutenção e a depuração do código. Com os padrões claramente definidos, torna-se mais simples identificar e modificar blocos lógicos específicos conforme necessário, sem afetar o restante do código.
  • Algoritmos mais expressivos: O casamento de padrões permite que os desenvolvedores expressem algoritmos de uma maneira mais natural e intuitiva. Ao alinhar as estruturas de código com os paradigmas de resolução de problemas, o casamento de padrões facilita a criação de algoritmos que se assemelham bastante aos seus modelos conceituais.

Types of Pattern Matching in C#

A correspondência de padrões é suportada pelas seguintes expressões:

  • is expressão
  • switch declarações
  • switch expressões

Os seguintes padrões podem ser usados ​​para correspondência com as construções:

Padrões de Declaração e Tipo

Em C#, os padrões de declaração e de tipo são ferramentas essenciais para verificar a compatibilidade dos tipos de tempo de execução das expressões com os tipos especificados. Com os padrões de declaração, você pode verificar a compatibilidade e declarar uma nova variável local simultaneamente. Considere o seguinte exemplo:

object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: iron software is awesome!
}

Aqui, o padrão de declaração garante que, se a expressão greeting corresponder ao tipo string, ele seja atribuído à variável message, possibilitando operações subsequentes.

O padrão Declaration é válido quando qualquer uma das seguintes condições for verdadeira:

  • O tipo em tempo de execução da expressão é T.
  • O tipo em tempo de execução da expressão deriva de T, implementa a interface T ou pode ser convertido implicitamente para T.
  • O tipo em tempo de execução da expressão é um tipo de valor anulável com o tipo subjacente T.
  • Existe uma conversão de boxing ou unboxing do tipo em tempo de execução da expressão para o tipo T.

Considere o seguinte exemplo que demonstra as condições acima:

int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
    Console.WriteLine(a + b);  // output: 53
}

Aqui, nullableX corresponde ao padrão porque é um tipo de valor anulável com o tipo subjacente int, e boxedy corresponde porque pode ser descompactado para int.

Quando você só precisa verificar o tipo de expressão sem declarar uma nova variável, pode utilizar o descarte _, conforme visto no exemplo abaixo:

public static decimal CalculateToll(Vehicle vehicle) => vehicle switch
{
    Bus _ => 4.00m,
    Motor _ => 8.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};

Neste trecho, o _ serve como um marcador para qualquer tipo que corresponda a Vehicle.

Tanto a declaração quanto os padrões de tipo garantem que as expressões não sejam nulas antes da correspondência de padrões. Você pode verificar se um valor não é nulo usando um padrão de constante nula negada, conforme ilustrado abaixo:

if (inputVal is not null)
{
    // ...
}

Esta negação garante que inputVal não seja nulo antes de prosseguir com outras operações.

Ao aproveitar os padrões de declaração e tipagem em seu código C#, você pode melhorar a legibilidade, reduzir o número de linhas de código e expressar algoritmos de forma mais eficaz. Esses padrões fornecem uma maneira concisa e expressiva de lidar com a lógica baseada em tipos e melhoram a capacidade de manutenção do seu código.

Padrão constante

Padrões constantes servem para verificar se o resultado de uma expressão corresponde a um valor constante específico. Considere o seguinte exemplo:

public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
    1 => 2.0m,
    2 => 10.0m,
    3 => 25.0m,
    4 => 60.0m,
    0 => 0.0m,
    _ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};

Aqui, os padrões constantes verificam se visitorCount corresponde a algum dos valores constantes especificados e retornam os preços dos ingressos correspondentes.

Em um padrão constante, você pode empregar vários tipos de expressões constantes, tais como:

  1. Literais numéricos inteiros ou de ponto flutuante.
  2. Personagens.
  3. Literais de cadeia.
  4. Valores booleanos (true ou false).
  5. Valores de enumeração.
  6. O nome de um campo constante ou variável local declarada.
  7. null.

Uma expressão do tipo Span<char> ou ReadOnlySpan<char> pode corresponder a strings constantes.

Para verificar null, utilize um padrão constante da seguinte forma:

if (inputVal is null)
{
    return;
}

Aqui, o padrão garante que inputVal é nulo antes de prosseguir com outras operações.

Você também pode usar um padrão de constante nula negada para determinar valores não nulos:

if (inputVal is not null)
{
    // ...
}

Este padrão verifica que inputVal não é nulo, permitindo que operações subsequentes sejam realizadas com segurança.

Ao incorporar padrões constantes em seu código C#, você pode lidar eficazmente com cenários em que valores constantes específicos precisam ser correspondidos, melhorando a clareza e a manutenção do código.

Padrões Relacionais

Os padrões relacionais fornecem um meio de comparar os resultados das expressões com constantes. Considere o seguinte exemplo:

Console.WriteLine(Classify(20));  // output: Too high
Console.WriteLine(Classify(double.NaN));  // output: Unknown
Console.WriteLine(Classify(4));  // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 => "Too high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};

Aqui, os padrões relacionais comparam measurement contra limites específicos para determinar sua classificação.

A parte à direita de um padrão relacional deve ser uma expressão constante, que pode ser de um tipo inteiro, ponto flutuante, char ou enum. Os operadores <, >, <=, >= podem ser usados no lado esquerdo.

Para comparar o resultado de uma expressão dentro de um determinado intervalo, utilize a conjunção "e", conforme ilustrado abaixo:

Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12)));  // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12)));  // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12)));  // output: winter

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    >= 3 and < 6 => "spring",
    >= 6 and < 9 => "summer",
    >= 9 and < 12 => "autumn",
    12 or (>= 1 and <3) => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};

Este excerto descreve como a conjunção "e" é utilizada para determinar a estação do ano no calendário, com base no mês que se enquadra em intervalos específicos. O texto também menciona que os padrões relacionais fornecem um meio conciso e expressivo de comparar os resultados das expressões com constantes, melhorando assim a clareza e a facilidade de manutenção do código.

Padrão de descarte

O padrão de descarte, denotado por _, serve para corresponder a qualquer expressão, incluindo null. Considere o seguinte exemplo:

Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday));  // output: 5.0
Console.WriteLine(GetDiscountInPercent(null));  // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10));  // output: 0.0

static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
    DayOfWeek.Monday => 0.5m,
    DayOfWeek.Tuesday => 12.5m,
    DayOfWeek.Wednesday => 7.5m,
    DayOfWeek.Thursday => 12.5m,
    DayOfWeek.Friday => 5.0m,
    DayOfWeek.Saturday => 2.5m,
    DayOfWeek.Sunday => 2.0m,
    _ => 0.0m,
};

No exemplo de padrão de descarte acima, ele lida com todos os valores de entrada possíveis. Todos os dias da semana são gerenciados e um valor padrão é fornecido. Dessa forma, todos os valores possíveis são tratados. O padrão de descarte não pode ser utilizado como um padrão em uma expressão is ou uma declaração switch. Nesses casos, um padrão var pode ser usado com um descarte, como var _, para corresponder a qualquer expressão. No entanto, um padrão de descarte é permitido em uma expressão switch. Para obter mais detalhes, consulte a seção Padrão de descarte da nota de proposta de recurso.

Padrões Lógicos

Em C#, os padrões lógicos oferecem ferramentas poderosas para correspondência de padrões, incluindo negação, conjunção e disjunção, que permitem condições de correspondência mais flexíveis e expressivas.

Negação (padrão not)

O padrão de negação, representado por not, corresponde a uma expressão quando o padrão negado não corresponde à expressão. Isso é particularmente útil para verificar se uma expressão não é nula, como demonstrado abaixo:

if (input is not null)
{
    // ...
}

Aqui, o bloco de código é executado se input não for nulo.

Conjuntivo (padrão and)

O padrão conjuntivo, usando a palavra-chave and, corresponde a uma expressão quando ambos os padrões correspondem à expressão. Isso permite combinar múltiplas condições, como ilustrado no exemplo a seguir:

Console.WriteLine(Classify(13));    // output: High
Console.WriteLine(Classify(-100));  // output: Too low
Console.WriteLine(Classify(5.7));   // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -40.0 => "Too low",
    >= -40.0 and < 0 => "Low",
    >= 0 and < 10.0 => "Acceptable",
    >= 10.0 and < 20.0 => "High",
    >= 20.0 => "Too high",
    double.NaN => "Unknown",
};

Neste exemplo, o measurement é classificado com base em seu intervalo de valores.

Disjuntivo (padrão or)

O padrão disjuntivo, usando a palavra-chave or, corresponde a uma expressão quando qualquer padrão corresponde à expressão. Isso permite lidar com múltiplas condições possíveis, conforme mostrado abaixo:

Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19)));  // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9)));  // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11)));  // output: spring

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    3 or 4 or 5 => "spring",
    6 or 7 or 8 => "summer",
    9 or 10 or 11 => "autumn",
    12 or 1 or 2 => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};

Aqui, a estação do ano no calendário é determinada com base no mês da data fornecida.

Esses combinadores de padrões podem ser usados ​​repetidamente para criar condições de correspondência mais complexas e precisas, aumentando a flexibilidade e a legibilidade do seu código.

Padrão de propriedade

O padrão de propriedade permite a correspondência das propriedades ou campos de uma expressão com padrões aninhados. Um exemplo disso pode ser visto no seguinte trecho de código:

static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };

Neste caso, o padrão da propriedade garante que a data fornecida corresponda a um dos dias de conferência especificados.

Você também pode incorporar uma verificação de tipo em tempo de execução e uma declaração de variável dentro de um padrão de propriedade, como mostrado abaixo:

static string TakeFive(object input) => input switch
{
    string { Length: >= 5 } s => s.Substring(0, 5),
    string s => s,
    ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
    ICollection<char> symbols => new string(symbols.ToArray()),
    null => throw new ArgumentNullException(nameof(input)),
    _ => throw new ArgumentException("Unsupported input type."),
};

Aqui, o padrão de propriedade é usado para lidar com strings e coleções de caracteres, garantindo o tratamento adequado com base em suas propriedades.

Padrão Posicional

Em C#, o padrão posicional permite desconstruir o resultado de uma expressão e comparar os valores resultantes com os padrões aninhados correspondentes. Por exemplo:

public readonly struct Point
{
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) => (X, Y) = (x, y);
    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}

static string Classify(Point point) => point switch
{
    (0, 0) => "Origin",
    (1, 0) => "Positive X basis end",
    (0, 1) => "Positive Y basis end",
    _ => "Just a point",
};

Neste exemplo, o padrão posicional é utilizado para classificar pontos com base em suas coordenadas.

Além disso, você pode referenciar propriedades ou campos aninhados dentro de um padrão de propriedade, conhecido como padrão de propriedade estendido, introduzido no C# 10:

static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start.Y: 0 } or { End.Y: 0 };

Essa funcionalidade aumenta a flexibilidade dos padrões de propriedades, permitindo o acesso direto a propriedades aninhadas.

Esses padrões fornecem mecanismos poderosos para lidar com estruturas de dados complexas e melhorar a legibilidade e a expressividade do seu código.

Padrão de Var

O padrão Var permite que você encontre correspondências para qualquer tipo. Isso pode ser particularmente útil para capturar resultados intermediários em expressões booleanas ou quando várias verificações são necessárias em estruturas de verificação switch case.

Aqui está um exemplo que demonstra o uso do padrão var em uma expressão booleana:

static bool IsAcceptable(int id, int absLimit) =>
    SimulateDataFetch(id) is var results 
    && results.Min() >= -absLimit 
    && results.Max() <= absLimit;

static int [] SimulateDataFetch(int id)
{
    var rand = new Random();
    return Enumerable
               .Range(start: 0, count: 5)
               .Select(s => rand.Next(minValue: -10, maxValue: 11))
               .ToArray();
}

Neste exemplo, SimulateDataFetch retorna uma matriz de inteiros, e o padrão is var captura o resultado na variável results, permitindo cálculos subsequentes com base em suas propriedades.

Além disso, os padrões de variáveis ​​podem ser utilizados em expressões ou instruções switch para um código mais conciso e legível. Aqui está um exemplo usando o padrão var em instruções switch case:

public record Point(int X, int Y);

static Point Transform(Point point) => point switch
{
    var (x, y) when x < y => new Point(-x, y),
    var (x, y) when x > y => new Point(x, -y),
    var (x, y) => new Point(x, y),
};

static void TestTransform()
{
    Console.WriteLine(Transform(new Point(1, 2)));  // output: Point { X = -1, Y = 2 }
    Console.WriteLine(Transform(new Point(5, 2)));  // output: Point { X = 5, Y = -2 }
}

Neste exemplo, o padrão var (x, y) captura as coordenadas do ponto, permitindo diferentes transformações com base em seus valores.

Em um padrão var, o tipo da variável declarada é inferido a partir do tipo da expressão que está sendo comparada com o padrão em tempo de compilação.

O padrão var oferece uma maneira conveniente de lidar com vários cenários em que o tipo específico de expressão não é conhecido antecipadamente, melhorando a clareza e a flexibilidade do código.

Apresentando a Biblioteca IronPDF

IronPDF Document Rendering é uma biblioteca da Iron Software especializada na geração de documentos PDF. Para começar, o primeiro passo é instalar a biblioteca a partir do gerenciador de pacotes NuGet ou do gerenciador de pacotes do Visual Studio.

# To install from the NuGet Package Manager Console
Install-Package IronPdf
SHELL

A imagem abaixo mostra como instalar a partir do Guia de Instalação do Visual Studio .

Expressões de Correspondência de Padrões em C# (Como Funciona para Desenvolvedores): Figura 1 - Instalando IronPDF com o gerenciador de pacotes NuGet

No código abaixo, veremos como gerar um documento PDF simples:

using IronPdf;

namespace IronPatterns
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("-----------Iron Software-------------");
            var renderer = new ChromePdfRenderer(); // var pattern
            var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";

            // Declaration Pattern
            int? nullableX = 8;
            int y = 45;
            object boxedy = y;
            content += "<p>Declaration Pattern</p>";
            if (nullableX is int a && boxedy is int b)
            {
                Console.WriteLine(a + b); // output: 53
                content += $"<p>Output: {(a + b)}</p>";
            }

            // Relational patterns
            content += "<p>Relational patterns</p>";
            var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
            Console.WriteLine(season1);
            content += $"<p>2024, 2, 25: {season1}</p>";
            var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
            Console.WriteLine(season2);
            content += $"<p>2024, 5, 25: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</p>";

            var pdf = renderer.RenderHtmlAsPdf(content);
            pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF        
        }

        static string GetCalendarSeason(DateTime date) => date.Month switch
        {
            >= 3 and < 6 => "spring",
            >= 6 and < 9 => "summer",
            >= 9 and < 12 => "autumn",
            12 or (>= 1 and < 3) => "winter",
            _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
        };
    }
}

Saída

Expressões de Correspondência de Padrões em C# (Como Funciona para Desenvolvedores): Figura 2

Detalhes do código

Aqui estamos usando a classe ChromePdfRenderer do IronPDF para salvar a string HTML em um documento PDF. O resultado é salvo no documento "output.pdf".

Licença de teste

O IronPDF pode ser usado com uma licença de avaliação obtida na página de licenciamento do IronPDF . Forneça um endereço de e-mail para gerar uma chave de licença que será enviada para o seu e-mail.

"IronPdf.LicenseKey": "<Your Key>"

Coloque a chave de licença no arquivo appsettings.json conforme mostrado acima.

Conclusão

Em C#, as expressões de correspondência de padrões oferecem uma maneira poderosa e flexível de escrever instruções condicionais, verificações de tipo e desconstruções de objetos de forma concisa e legível. Ao aproveitar o casamento de padrões, os desenvolvedores podem aprimorar a clareza e a facilidade de manutenção de seu código, reduzindo o código repetitivo e a redundância. Seja para verificação de tipos, instruções switch ou desconstrução, as expressões de correspondência de padrões fornecem um conjunto de ferramentas versátil para lidar com uma ampla gama de tarefas de programação em C#.

Em resumo, dominar expressões de correspondência de padrões pode melhorar significativamente suas habilidades de programação em C#, permitindo que você escreva um código mais limpo, expressivo e fácil de entender e manter. Também abordamos os recursos de geração de PDF a partir de HTML do IronPDF , que podem ser utilizados para gerar documentos PDF.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais bem estruturados e visualmente atraentes.

...
Leia mais

Artigos relacionados

Key in blue circle

Obtenha sua chave de avaliação gratuita de 30 dias instantaneamente.

Your trial license will be sent to your email address

Sem limitações. 100% desbloqueado. Sem cartão de crédito.

bullet_checkedNão é necessário cartão de crédito nem criação de conta.Sem limitações. 100% desbloqueado. Sem cartão de crédito.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Agende sua demonstração ao vivo gratuita.
Booking Badge

Aprovado por milhões de engenheiros em todo o mundo.

Logotipos dos clientes da Iron Software
Agende sua consulta sem compromisso.
Preencha o formulário abaixo ou envie um e-mail para sales@ironsoftware.com
Os seus dados serão sempre mantidos em sigilo.
Aprovado por milhões de engenheiros em todo o mundo.
Logotipos dos clientes da Iron Software
Obtenha sua chave de avaliação gratuita de 30 dias instantaneamente.
Não é necessário cartão de crédito nem criação de conta.