Добавлю свои 5 копеек. Хочу написать про небезопасность перегрузки функций (когда есть несколько функций с одинаковым именем, но разными типами параметров или разным количеством параметров. Недавно сделал ошибку из-за перегрузки операторов в C#.
Был код следующего вида:
void Func(BaseType t);
{
if (t is ChildType) { Func((ChildType)t); }
}

void Func(ChildType c);
{
// some code
}

Когда добавил дополнительный параметр в
void Func(ChildType c, int additionalParameter)
и исправил в одном месте, не учел, что есть еще код, который я привел выше.

И это привело к бесконечной рекурсии и падению программы во время исполнения (на автоматических юнит тестах, но все же).

Вывод перегрузка функций опасна тем, что при изменении списка параметров или добавления, или удаления одной из перегруженных функций, компилятор может автоматически подставить в место вызова другую функцию, при этом не будет ошибок компиляции и такую ошибку сложно заметить.