Introdução: A lenda do C# "morto"
Você provavelmente já ouviu que C# é uma linguagem para "corporativos", onde tudo é chato, lento e coberto por uma camada de burocracia empresarial. Mas a verdade é que o desenvolvedor C# hoje é um soldado universal de TI. Ele escreve microsserviços rápidos em ASP.NET Core, otimiza consultas ao banco de dados via Entity Framework e, às vezes, até incorpora aprendizado de máquina com ML.NET.
Neste artigo, não vou falar de teorias abstratas. Vamos percorrer o dia de trabalho típico de um programador C# em uma empresa real: do café matinal ao push de código para produção. Você verá exemplos de código, ferramentas e truques que economizam horas de trabalho.
08:30 — Manhã: Café, e-mail e quadro de tarefas
O dia não começa com código, mas com contexto. A primeira coisa que faço é abrir o Slack e o Jira. Em uma equipe típica, há o standup matinal (daily stand-up). Nele, respondemos a três perguntas:
- O que foi feito ontem?
- O que farei hoje?
- Há algum impedimento?
Após o standup, uma rápida revisão dos pull requests dos colegas. A revisão de código em C# não é apenas uma "formalidade". Aqui é importante verificar se não há vazamento de memória (especialmente com IDisposable) e se o async/await está sendo usado corretamente.
Exemplo da vida real: revisão de código de um método assíncrono
// Ruim: chamada bloqueante dentro de um método asyncpublic async Task<User> GetUserAsync(int id){ var user = _context.Users.Find(id); // .Find — síncrono! return await Task.FromResult(user); // Invólucro inútil}
// Bom: totalmente assíncronopublic async Task<User> GetUserAsync(int id){ return await _context.Users.FindAsync(id); // Assincronia real}Esse pequeno detalhe pode matar a performance sob carga. Por isso, o programador C# deve monitorar a assincronia a cada passo.
10:00 — Trabalhando na tarefa: Criando um novo endpoint de API
Hoje no backlog está a tarefa "Adicionar filtragem de produtos por preço". Essa é uma história típica para um desenvolvedor .NET. Trabalho no Visual Studio 2022 com ReSharper (sim, ele é lento, mas sem ele é como ficar sem as mãos).
Passo 1: Modelo e DTO
Primeiro, definimos o modelo de dados. Suponha que temos Entity Framework Core e banco PostgreSQL.
public class Product{ public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; }}
public class ProductFilterDto{ public decimal? MinPrice { get; set; } public decimal? MaxPrice { get; set; } public string? Category { get; set; }}Passo 2: Repositório com IQueryable
O truque principal é não trazer todos os dados para a memória, mas usar IQueryable. Isso permite formar a consulta SQL no lado do banco.
public async Task<List<Product>> GetFilteredProductsAsync(ProductFilterDto filter){ var query = _context.Products.AsQueryable();
if (filter.MinPrice.HasValue) query = query.Where(p => p.Price >= filter.MinPrice.Value);
if (filter.MaxPrice.HasValue) query = query.Where(p => p.Price <= filter.MaxPrice.Value);
if (!string.IsNullOrEmpty(filter.Category)) query = query.Where(p => p.Category == filter.Category);
return await query.ToListAsync();}Observe: não chamamos .ToList() até o final. Esse é um padrão básico, mas criticamente importante para qualquer desenvolvedor C#.
Passo 3: Controlador ASP.NET Core
[ApiController][Route("api/[controller]")]public class ProductsController : ControllerBase{ private readonly IProductRepository _repo;
public ProductsController(IProductRepository repo) =&g