Módulo 1 · C# — Capítulo 04

Métodos e Parâmetros

Organizando código em blocos reutilizáveis — e os modificadores ref/out/in que decidem se um parâmetro é copiado ou compartilhado.

1. Anatomia de um método

C# estrutura básica
public decimal CalcularTotal(List<decimal> precos, decimal desconto = 0)
{
    decimal soma = precos.Sum();
    return soma - desconto;
}
ParteSignificado
publicModificador de acesso (capítulo 5)
decimalTipo de retorno — void se não retorna nada
CalcularTotalNome, convenção PascalCase em C# (diferente do camelCase do JS)
(List<decimal> precos, decimal desconto = 0)Parâmetros — o segundo tem valor padrão, tornando-o opcional

2. Sobrecarga de métodos (overloading)

C# permite múltiplos métodos com o mesmo nome, desde que a lista de parâmetros seja diferente (tipo ou quantidade). O compilador escolhe qual chamar com base nos argumentos — algo que não existe em JavaScript, onde só a última função com aquele nome "vence".

C# overloading
public decimal CalcularTotal(List<decimal> precos) => precos.Sum();

public decimal CalcularTotal(List<decimal> precos, decimal desconto)
    => precos.Sum() - desconto;

// o compilador escolhe a versão certa pela quantidade de argumentos
CalcularTotal(listaDePrecos);
CalcularTotal(listaDePrecos, 10m);

3. Argumentos nomeados

Você já viu isso do lado do T-SQL (EXEC proc @Param = valor) — em C# existe o equivalente exato, útil quando um método tem vários parâmetros opcionais:

C# named arguments
void CriarCliente(string nome, string email, bool ativo = true, string? telefone = null) { ... }

// sem nomear, a ordem importa
CriarCliente("Ana", "ana@x.com", true, "11999999999");

// nomeando, a ordem não importa e a intenção fica explícita
CriarCliente(nome: "Ana", email: "ana@x.com", telefone: "11999999999");

4. ref, out e in — controlando como o parâmetro é passado

Por padrão, tipos por valor (capítulo 2) são copiados ao entrar num método — alterações dentro do método não afetam a variável original. Três modificadores mudam esse comportamento:

ModificadorEfeitoPrecisa inicializar antes de passar?
refPassa por referência — alterações dentro do método refletem foraSim
outPassa por referência, mas o método é obrigado a atribuir um valorNão
inPassa por referência só para evitar cópia (performance), mas o método não pode alterarSim
C# ref e out em ação
void Dobrar(ref int numero) => numero *= 2;

int valor = 5;
Dobrar(ref valor);
Console.WriteLine(valor); // 10

bool TentarDividir(int a, int b, out int resultado)
{
    if (b == 0) { resultado = 0; return false; }
    resultado = a / b;
    return true;
}

if (TentarDividir(10, 2, out int quociente))
    Console.WriteLine(quociente); // 5
Conectando com o Módulo 2

out em C# é conceitualmente o mesmo papel de um parâmetro OUTPUT em uma Stored Procedure — o método/procedure "devolve" um valor por um canal que não é o retorno principal. TryParse, que você viu no capítulo 2, é exatamente esse padrão: bool de sucesso + out com o valor.

5. params — quantidade variável de argumentos

C# params
decimal Somar(params decimal[] valores) => valores.Sum();

Somar(10, 20, 30);       // chama com quantos argumentos quiser
Somar();                 // também válido — soma 0

6. Métodos com corpo de expressão e funções locais

C# sintaxe concisa
// expression-bodied member — equivalente a uma arrow function de uma linha
decimal Dobro(decimal x) => x * 2;

// função local — só existe dentro do método que a declara
decimal CalcularComDesconto(decimal preco, decimal percentual)
{
    decimal AplicarDesconto(decimal valor) => valor - (valor * percentual / 100);
    return AplicarDesconto(preco);
}

Uma função local é o parente mais próximo de uma função aninhada em JavaScript — existe só dentro do escopo do método que a contém, útil para uma lógica auxiliar pequena que não merece virar um método separado da classe.

7. Onde isso te leva

Com métodos dominados — inclusive como controlar se um parâmetro é copiado ou compartilhado — o próximo passo é organizar métodos e dados juntos dentro de classes: o início de orientação a objetos.

📌 Resumo do capítulo

  • C# permite sobrecarga de métodos (mesmo nome, parâmetros diferentes) — o compilador escolhe pela assinatura.
  • Argumentos nomeados (nome: valor) tornam chamadas com muitos parâmetros opcionais mais legíveis.
  • ref/out/in alteram como um parâmetro é passado — out é o parente direto de um parâmetro OUTPUT de procedure.
  • params aceita uma quantidade variável de argumentos como array.

✏️ Praticando

  1. Escreva duas sobrecargas de um método Formatar: uma que recebe só um decimal, outra que recebe um decimal e uma string de moeda (ex: "R$", "US$").
  2. Escreva um método bool TentarObterCliente(int id, out Cliente? cliente) que simula uma busca (pode usar uma lista fixa em memória).
  3. Escreva um método com params int[] numeros que devolve o maior valor recebido.