Заставить мой код использовать мой метод расширения

Я использую ведение журнала BitFactory, которое предоставляет множество таких методов:

public void LogWarning(object aCategory, object anObject)

У меня есть метод расширения, который делает это немного лучше для наших потребностей в регистрации:

public static void LogWarning(this CompositeLogger logger, 
      string message = "", params object[] parameters)

Что только что завершает некоторые общие операции регистрации, и означает, что я могу записывать как:

Logging.LogWarning("Something bad happened to the {0}. Id was {1}",foo,bar);

Но когда у меня есть только одна строка в моем params object[], тогда мой метод расширения не будет вызываться, вместо этого будет выбран исходный метод.

Помимо обозначения моего метода что-то еще, есть ли способ, которым я могу остановить это?

Ответы

Ответ 1

Правила о том, как перегруженные методы разрешены одному (или ошибке), сложны (спецификация С# включена в Visual Studio для всех деталей gory).

Но существует одно простое правило: методы расширения рассматриваются только в том случае, если не существует возможного члена, который можно вызвать.

Поскольку подпись двух объектов будет принимать любые два параметра, любой вызов с двумя параметрами будет соответствовать этому элементу. Таким образом, никакие методы расширения не рассматриваются как возможности.

Вы можете передать третий параметр (например, String.Empty) и не использовать его в формате.

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

PS. нет смысла иметь параметр по умолчанию для параметра message: он никогда не будет использоваться, если вы не передадите никаких аргументов: но это ничего не будет записывать.

Ответ 2

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

например:

LoggerExtensions.LogWarning(Logging, "Something bad happened to the {0}. Id was {1}",foo,bar);

Я предполагаю, что расширение объявляется в классе с именем LoggerExtensions

Ответ 3

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

logger.LogWarning("Something bad happened to the {0}.", parameters: "foo");