Перегруженные методы дают предупреждение "Метод с необязательным параметром скрыт от перегрузки" в Resharper

У меня есть несколько приложений на С#, которые выполняют протоколирование, а метод вывода имеет перегрузку, чтобы принять сообщение и StreamWriter, а другая перегрузка с дополнительным параметром для массива params. Пример сигнатур метода:

private static void Output(string message, StreamWriter writer, params object[] args) 
{..}

private static void Output(string message, StreamWriter writer) 
{..}

Вопрос касается Resharper, который дает следующее предупреждение для этих методов: " Метод с дополнительным параметром скрыт при перегрузке".

Предупреждение вводит в заблуждение, потому что я вызываю перегрузку с двумя параметрами из 3-х перегрузок параметров и не приводит к рекурсивному вызову, поэтому перегрузка не скрыта.

Я провел некоторое исследование на сайте Resharper, и в этом выпуске были открыты некоторые билеты, которые были закрыты как "не исправить".

Мне кажется, что это допустимый прецедент, так как среда выполнения знает, какая перегрузка для вызова. Также есть примеры в .NET framework, где они используют такие перегрузки.

Например, StreamWriter.WriteLine() имеет перегрузки для значения для записи, а также Format params.

Является ли это допустимым аргументом или мои методы будут переименованы в нечто вроде "OutputFormat", поскольку за кулисами они используют string.Format для построения строки с указанными параметрами?

Ответы

Ответ 1

Насколько я вижу, в вашем посте есть два вопроса.

Прежде всего, если вы чувствуете, что ваши методы могут быть переименованы в нечто более очевидное, это улучшит ваш код по многим аспектам (читаемость, удобство использования и т.д.), и они должны в любом случае описать как можно ближе, что они делают.

Второй, о предупреждении Resharper:

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

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

private static void Print(int i) {...}

private static void Print(bool b) {...}

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

Основное объяснение

Если у вас есть что-то вроде этого:

private static void Print(string message) {...}

private static void Print(string message, string messageDelimiter = "===\n") {...}

Когда вы вызовете функцию Print из своего класса, поскольку обе функции будут выглядеть одинаково, когда вы их вызываете: Print("my message"); скрытый параметр с дополнительным параметром.

Таким образом, вы могли бы просто объединить их так:

private static void Print(string message, string messageDelimiter = "===\n") {...}

Более того

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

public static void Print(string message) {...} //< As you can see this one is public

private static void Print(string message, string messageDelimiter = "===\n") {...}

Даже в этом случае вы столкнетесь с той же проблемой.

IMO, хорошее эмпирическое правило - задать себе несколько вопросов:

  • Имеет ли дополнительный параметр действительно смысл, где он находится?
  • Действительно ли функция должна содержать одно и то же имя?
  • Должен ли параметр быть необязательным?

Если вы ответите "да" всем им, это может быть "нормально" игнорировать комментарий Resharper и позволить вашему коду как есть.