Что такое перегрузка методов в C# и чем она отличается от переопределения?
Слышал термины «перегрузка» (overload) и «переопределение» (override) — постоянно их путаю. Что такое перегрузка методов и можно ли иметь два метода с одинаковым именем?
int Sum(int a, int b) => a + b;
double Sum(double a, double b) => a + b;
2 ответа
Да, можно — это и есть перегрузка (overloading): несколько методов с одинаковым именем, но разным набором параметров (по количеству или типам). Компилятор сам выбирает подходящий по аргументам вызова.
class Printer
{
public void Print(int x) => Console.WriteLine($"int: {x}");
public void Print(string x) => Console.WriteLine($"string: {x}");
public void Print(int a, int b) => Console.WriteLine($"два: {a},{b}");
}
var p = new Printer();
p.Print(5); // int: 5
p.Print("hi"); // string: hi
p.Print(1, 2); // два: 1,2
Важно: перегрузка различается только по параметрам, а НЕ по типу возврата. Вот это не скомпилируется:
int Get() => 1;
// double Get() => 1.0; // ОШИБКА: отличается только тип возврата
Не путайте с переопределением (override):
- Перегрузка — несколько методов с одним именем в одном классе, разные параметры, выбор на этапе компиляции.
- Переопределение — потомок заменяет
virtual-метод родителя тем же сигнатурой, выбор в рантайме (полиморфизм).
Классический пример перегрузки из библиотеки — Console.WriteLine, у которого десятки версий под разные типы аргумента.
Удобная альтернатива многим перегрузкам — необязательные параметры со значениями по умолчанию:
void Greet(string name, string greeting = "Привет")
=> Console.WriteLine($"{greeting}, {name}!");
Greet("Аня"); // Привет, Аня!
Greet("Боря", "Здорово"); // Здорово, Боря!
Часто это чище, чем заводить отдельную перегрузку под каждый случай. Но если поведение реально разное под разные типы — нужна именно перегрузка.