Programação Funcional em C#: Guia Prático

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Funcional em C#: uma abordagem moderna para o desenvolvimento



Programação Funcional (PF) é um paradigma no qual os cálculos são tratados como avaliação de funções matemáticas e evita-se a mudança de estado e dados mutáveis. Embora C# tenha sido originalmente criado como uma linguagem orientada a objetos, a partir da versão 3.0 ele tem incorporado ativamente elementos da abordagem funcional. Hoje, a programação funcional em C# não é apenas uma tendência da moda, mas uma ferramenta poderosa para escrever código mais previsível, testável e seguro para paralelismo.



Neste artigo, vamos explorar os conceitos-chave da PF aplicados ao C#: funções puras, imutabilidade de dados, LINQ, closures e expressões lambda. Você verá como essas técnicas ajudam a escrever código conciso e confiável no ecossistema .NET.



1. Funções Puras e Ausência de Efeitos Colaterais



Uma função pura é uma função que:

  • Sempre retorna o mesmo resultado para os mesmos argumentos (transparência referencial).
  • Não possui efeitos colaterais (não altera variáveis globais, não realiza entrada/saída, não modifica os argumentos recebidos).


Em C#, uma função pura pode ser assim:



// Função purapublic int AddPure(int a, int b){    return a + b;}

// Função NÃO pura (efeito colateral — saída no console e alteração de variável global)private int _state = 0;public int AddImpure(int a, int b){ _state++; Console.WriteLine("Chamada de função"); return a + b + _state;}


As vantagens das funções puras são óbvias: são fáceis de testar, previsíveis e podem ser chamadas com segurança a partir de threads paralelas. Tente extrair toda a lógica não relacionada a I/O para funções puras.



2. Imutabilidade de Dados (Immutability)



A programação funcional incentiva o trabalho com dados imutáveis. Em vez de modificar um objeto existente, você cria um novo objeto com as propriedades alteradas. Em C#, os seguintes recursos são excelentes para isso:

  • record (a partir do C# 9) — tipo referencial com igualdade baseada em valor e imutabilidade por padrão.
  • struct — para pequenas estruturas imutáveis (por exemplo, coordenadas, dinheiro).
  • IEnumerable<T> — para coleções imutáveis via LINQ.


Exemplo com record:



public record Person(string Name, int Age);

// Uso da expressão with para criar uma cópia com alteraçõesvar original = new Person("Alexey", 30);var updated = original with { Age = 31 };

Console.WriteLine(original); // Person { Name = Alexey, Age = 30 }Console.WriteLine(updated); // Person { Name = Alexey, Age = 31 }


Essa abordagem elimina a alteração acidental de dados em um local que afeta outras partes do programa.



3. LINQ — Consultas Funcionais a Dados



LINQ (Language Integrated Query) é, talvez, o exemplo mais marcante da abordagem funcional em C#. Ele permite processar coleções de forma declarativa, usando encadeamento de métodos.



Métodos funcionais chave do LINQ:

  • Select — transformação de cada elemento (análogo ao map).
  • Where — filtragem (análogo ao filter).
  • Aggregate — redução (análogo ao reduce).
  • SelectMany — desdobramento de coleções aninhadas (flatMap).


Exemplo: encontrar a soma dos quadrados dos números pares.



int[] numbers = { 1, 2, 3, 4, 5, 6 };

// Estilo imperativoint sumImperative = 0;foreach (var num in numbers){ if (num % 2 == 0) { sumImperative += num * num; }}

// Estilo funcional com LINQint sumFunctional = numbers .Where(n => n % 2 == 0) // filtragem .Select(n => n * n) // transformação .Sum(); // agregação

C

Blogs

Book Recommendations