Заставить мой код использовать мой метод расширения
Я использую ведение журнала 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");