Sobrecarga de métodos em C#: o mesmo nome para ações diferentes
- Gerar link
- X
- Outros aplicativos

Resumo rápido
- Sobrecarga é ter vários métodos com o mesmo nome e parâmetros diferentes.
- O que precisa mudar é a assinatura: quantidade, tipo ou ordem dos parâmetros.
- Mudar só o tipo de retorno não conta como sobrecarga.
- O C# escolhe a versão certa pelos argumentos que você passa.
Console.WriteLineé sobrecarregado: por isso aceita texto, número e bool.
No jogo, curar pode acontecer de vários jeitos: com uma erva que cura um valor fixo, com uma quantidade escolhida, ou com um item que tem nome e potência. Criar CurarComErva, CurarComQuantidade e CurarComItem funciona, mas quem usa o código precisa decorar três nomes para a mesma ação.
A sobrecarga de métodos (em inglês, overloading) deixa você usar um nome só, Curar, com versões diferentes. Se ainda não viu métodos, comece pelo post de métodos em C#.
Mesmo nome, parâmetros diferentes

C#
class Program
{
static void Main()
{
int vida = 30;
vida = Curar(vida);
Console.WriteLine($"Erva comum: {vida}");
vida = Curar(vida, 40);
Console.WriteLine($"Kit médico: {vida}");
vida = Curar(vida, "Spray", 2);
Console.WriteLine($"Spray duplo: {vida}");
}
// versão 1: erva comum, cura 20
static int Curar(int vida)
{
return Math.Min(vida + 20, 100);
}
// versão 2: cura a quantidade escolhida
static int Curar(int vida, int quantidade)
{
return Math.Min(vida + quantidade, 100);
}
// versão 3: item com nome e potência
static int Curar(int vida, string item, int potencia)
{
Console.WriteLine($"Usando {item}...");
return Math.Min(vida + 10 * potencia, 100);
}
}
Saída esperada
Erva comum: 50
Kit médico: 90
Usando Spray...
Spray duplo: 100
Os três métodos se chamam Curar, mas cada um tem uma lista de parâmetros diferente. O Math.Min devolve o menor de dois números: é o jeito curto de garantir que a vida não passe de 100.
💡 Por que class Program aqui
No post de métodos os exemplos usavam código solto no topo do arquivo (top-level statements). Ali os métodos viram funções locais, e função local não aceita sobrecarga: o compilador reclama que Curar já existe. Por isso, para sobrecarregar, os métodos precisam estar dentro de uma classe, como o class Program com o Main.
Como o C# escolhe a versão

Na hora de compilar, o C# olha os argumentos da chamada e procura a versão cuja lista de parâmetros combina:
| Chamada | Argumentos | Versão escolhida |
|---|---|---|
Curar(vida) | um int | Curar(int vida) |
Curar(vida, 40) | dois int | Curar(int vida, int quantidade) |
Curar(vida, "Spray", 2) | int, string, int | Curar(int vida, string item, int potencia) |
Curar("Spray") | uma string | nenhuma: erro de compilação |
O nome do método junto com os tipos dos parâmetros forma a assinatura. Duas versões podem ter o mesmo nome desde que as assinaturas sejam diferentes.
O que conta como diferente
A assinatura muda quando muda a quantidade, o tipo ou a ordem dos tipos dos parâmetros:
C#
class Program
{
static void Main()
{
MostrarDano(15);
MostrarDano(15.5);
MostrarDano("Faca", 15);
MostrarDano(15, "Faca");
}
static void MostrarDano(int dano) => Console.WriteLine($"Dano inteiro: {dano}");
static void MostrarDano(double dano) => Console.WriteLine($"Dano decimal: {dano}");
static void MostrarDano(string arma, int dano) => Console.WriteLine($"{arma} causou {dano}");
static void MostrarDano(int dano, string arma) => Console.WriteLine($"{dano} de dano com {arma}");
}
Saída esperada
Dano inteiro: 15
Dano decimal: 15.5
Faca causou 15
15 de dano com Faca
O => é um atalho para métodos de uma linha só: static void X() => algo; é o mesmo que escrever o corpo entre chaves.
Repare que 15 vai para a versão int e 15.5 para a versão double: o C# sempre prefere a versão que combina exatamente com o tipo do argumento.
O que NÃO conta: só o tipo de retorno
Mudar apenas o tipo de retorno não cria uma nova assinatura. O C# não teria como saber qual versão você quer:
C#
static int Dano(int forca) { return forca * 2; }
static double Dano(int forca) { return forca * 2.5; } // erro: já existe Dano(int)
Nomes de parâmetros diferentes também não contam: Dano(int forca) e Dano(int nivel) têm a mesma assinatura.
Você já usa sobrecarga
O Console.WriteLine que você usa desde o primeiro dia tem várias versões: uma para string, uma para int, uma para bool, uma para double... Por isso todas estas linhas funcionam:
C#
Console.WriteLine("Porta trancada");
Console.WriteLine(42);
Console.WriteLine(true);
Console.WriteLine(3.75);
Saída esperada
Porta trancada
42
True
3.75
Sobrecarga ou valor padrão?
No post de métodos você viu parâmetros com valor padrão, que também deixam chamar o método com menos argumentos. Qual usar?
| Use | Quando |
|---|---|
| Valor padrão | a lógica é a mesma e só um valor muda (CalcularDano(10) e CalcularDano(10, 3)) |
| Sobrecarga | cada versão faz algo diferente ou recebe tipos diferentes (Curar(vida) e Curar(vida, "Spray", 2)) |
Erros comuns
1. Duas versões com a mesma assinatura. Mudar só o retorno ou o nome dos parâmetros gera erro de "já existe um membro com esses parâmetros".
2. Chamada ambígua. Se duas versões servem igualmente bem, o C# não escolhe e dá erro. Acontece mais com valores padrão misturados a sobrecargas: evite combinar os dois no mesmo nome.
3. Sobrecarregar no código solto do topo do arquivo. Funções locais não aceitam sobrecarga. Coloque os métodos dentro de uma classe.
4. Versões que fazem coisas sem relação. Curar(int) que cura e Curar(string) que salva o jogo confunde quem lê. Mesmo nome deve significar a mesma ação.
DESAFIO
Tente resolver antes de abrir a resposta. Sobreviveu? Vá para o próximo.
Estas duas versões podem existir juntas?
static void Atirar(int balas)estatic void Atirar(int quantidade)Ver resposta
Não. Os nomes dos parâmetros não contam; as duas têm a assinatura
Atirar(int).Qual versão roda em
MostrarDano(7.0), usando os quatroMostrarDanodo post?Ver resposta
MostrarDano(double dano), porque7.0é umdouble. A saída éDano decimal: 7.Escreva duas versões de
Recarregar: uma sem parâmetros que recarrega 15 balas e outra que recebe a quantidade. As duas devolvem o número de balas.Ver resposta
static int Recarregar() => 15;estatic int Recarregar(int quantidade) => quantidade;, dentro de uma classe (lembre: funções locais não aceitam sobrecarga).
Conclusão
Com a sobrecarga, a mesma ação tem o mesmo nome, não importa como ela é chamada: quem usa o seu código só precisa lembrar de Curar. É uma ideia simples que você vai encontrar em toda a biblioteca do .NET.
Até aqui, vida, balas e nome eram variáveis soltas. O próximo passo é juntar tudo isso num personagem de verdade, com classes e objetos.
📖 Continue a série: Classes e objetos em C#.
- Gerar link
- X
- Outros aplicativos
Comentários
Postar um comentário