1. Valores padrão para parâmetros
Imagina uma cafeteria: se você não disser se quer açúcar no café, o barista coloca uma colher por padrão. Mas às vezes você quer... duas! Ou até sem açúcar (coragem, hein!). Com métodos é igual: às vezes é prático que alguns parâmetros tenham valores padrão se você não passar nada.
E argumentos nomeados são tipo quando você pede: “O leite eu quero de soja, não o normal”, não importa a ordem dos ingredientes.
No C# esses dois esquemas deixam seu código mais limpo, fácil de entender e evitam bugs. Você vai ver isso direto em projetos reais: desde libs do .NET até frameworks famosos — por isso os chefes curtem quando você manja dessas coisas.
Sintaxe
O valor padrão de um parâmetro é definido direto na declaração do método usando o sinal =. Se você não passar esse parâmetro na chamada, o valor padrão é usado.
void PrintStudent(string name, int age = 18)
{
Console.WriteLine($"Estudante: {name}, idade: {age}");
}
Como funciona?
- Se chamar PrintStudent("Алиса"); — vai mostrar: Estudante: Алиса, idade: 18.
- Se chamar PrintStudent("Саша", 22); — vai mostrar: Estudante: Саша, idade: 22.
Funciona pra qualquer tipo?
Você pode definir valor padrão pra qualquer tipo de parâmetro, mas tem uns detalhes:
- Para tipos por referência (string, classes, etc): pode usar null ou um literal específico.
- Para tipos valor (int, double, bool, etc): coloca o literal do tipo certo.
- Para enums (enum), structs: também pode usar valores padrão.
void AddStudent(string name, int course = 1, double averageScore = 5.0, string comment = null)
{
Console.WriteLine($"Adicionado estudante: {name}, curso: {course}, média: {averageScore}, comentário: {comment}");
}
Chamadas:
- AddStudent("Иван");
- AddStudent("Мария", 2);
- AddStudent("Фёдор", 2, 4.7, "Com louvor");
Ordem dos parâmetros com valores
Todos os parâmetros opcionais (com valor padrão) têm que ficar à direita (depois dos obrigatórios). Se tentar colocar um parâmetro com valor padrão antes de um obrigatório, o compilador vai reclamar feio.
// Erro!
void Test(int a = 1, int b)
{
// ...
}
Por quê? Porque senão o compilador não consegue saber qual argumento vai pra qual parâmetro na chamada do método.
2. Argumentos nomeados
Por padrão, quando você chama um método e passa argumentos, a ordem tem que ser igual à ordem dos parâmetros na definição. Mas às vezes a lista é grande, alguns têm valor padrão, e é fácil se confundir.
Argumentos nomeados deixam você dizer exatamente pra qual parâmetro está passando cada argumento, em qualquer ordem.
AddStudent(name: "Елизавета", averageScore: 4.2, comment: "Melhor estudante do semestre");
- Aqui a gente não passa o curso (course), então ele vai ser 1 (padrão).
- Não precisa lembrar em que posição estava o parâmetro comment — só coloca o nome dele.
Você pode até trocar a ordem dos parâmetros:
AddStudent(averageScore: 3.7, name: "Георгий");
Isso é muito prático, e o código fica bem mais legível!
Usando junto com argumentos posicionais
Você pode misturar argumentos nomeados e posicionais (sem nome), mas todos os posicionais têm que vir antes dos nomeados.
// Certo
AddStudent("Сергей", averageScore: 4.9);
// Erro
AddStudent(course: 2, "Филипп");
Depois do primeiro argumento nomeado, o resto tem que ser só nomeado. O compilador é rígido com essa ordem pra te proteger de surpresas.
Facilidade em métodos com muitos parâmetros
Isso é muito usado quando o método tem um monte de opções extras. Por exemplo, se você fosse criar uma função pra adicionar usuário numa base na nuvem:
void RegisterUser(
string username,
string password,
string email = null,
bool admin = false,
bool sendWelcomeEmail = true,
string language = "ru"
)
Chamar sem argumentos nomeados fica bizarro:
RegisterUser("cat", "qwerty", null, false, true, "ru");
Com argumentos nomeados fica tudo claro e seguro:
RegisterUser("cat", "qwerty", admin: true, sendWelcomeEmail: false, language: "en");
Dica: use argumentos nomeados pra deixar o código legível até sem documentação!
3. Detalhes de implementação e erros comuns
Quando você começa a usar valores padrão e argumentos nomeados, pode errar em vários pontos.
- Ordem dos parâmetros. Sempre coloque os parâmetros com valor padrão depois dos obrigatórios. Se inverter, o compilador vai dar erro.
- Mudar valor padrão na biblioteca. Se você mudar o valor padrão numa biblioteca, os clientes antigos não vão usar o novo valor automaticamente. O valor padrão é compilado no código que chama. Então pensa bem antes de mudar valores padrão em libs públicas.
- Misturar argumentos posicionais e nomeados. Se você misturar os dois, mas depois de um nomeado tentar passar outro posicional — não vai rolar. Por exemplo: Func(a: 1, 2) — vai dar erro.
- Erro de digitação no nome do parâmetro. O compilador é chato: se você errar uma letra (tipo naem: "Миша"), vai receber um erro tipo: "Esse parâmetro não existe, o que você tá fazendo?!".
GO TO FULL VERSION