Я изучаю вход C#, и я не хочу, чтобы мои сообщения журнала провели любое время, обрабатывая, если сообщение ниже регистрирующегося порога. Лучшее я вижу log4net, делает пороговая проверка ПОСЛЕ оценки параметров журнала.
Пример:
_logger.Debug( "My complicated log message " + thisFunctionTakesALongTime() + " will take a long time" )
Даже если порог будет выше Отладки, то thisFunctionTakesALongTime будет все еще оценен.
В log4net Вы, как предполагается, используете _logger.isDebugEnabled, таким образом, Вы заканчиваете с
if( _logger.isDebugEnabled )
_logger.Debug( "Much faster" )
Я хочу знать, существует ли лучшее решение для .NET, регистрирующегося, который не включает проверку каждый раз, когда я хочу зарегистрироваться.
В C++ мне разрешают сделать
LOG_DEBUG( "My complicated log message " + thisFunctionTakesALongTime() + " will take no time" )
так как мой макрос LOG_DEBUG делает саму проверку уровня журнала. Это освобождает меня, чтобы иметь 1 сообщение журнала строки всюду по моему приложению, которое я значительно предпочитаю. Кто-либо знает о способе копировать это поведение в C#?
Если вы можете настроить таргетинг на .NET 3.5 (C # 3.0), вы можете использовать методы расширения , чтобы обернуть if
заявления.
, чтобы вы могли выполнить эквивалентный «макрос»:
logger.Log_Debug("Much faster");
logger.Log_Debug(() => { "My complicated log message " + thisFunctionTakesALongTime() + " will take no time" });
, заключив проверку в этот метод:
public class Log4NetExtensionMethods {
// simple string wrapper
public void Log_Debug(this log4net.ILog logger, string logMessage) {
if(logger.isDebugEnabled) {
logger.Debug(logMessage);
}
}
// this takes a delegate so you can delay execution
// of a function call until you've determined it's necessary
public void Log_Debug(this log4net.ILog logger, Func<string> logMessageDelegate) {
if(logger.isDebugEnabled) {
logger.Debug(logMessageDelegate());
}
}
}
17.4.2 Атрибут Conditional
Атрибут Conditional позволяет определять условные методы. Атрибут Conditional указывает условие путем тестирования символа условной компиляции. Вызов условного метода либо включаются, либо опускаются в зависимости от того, определен ли этот символ в точке вызова. Если символ определен, вызов включается; в противном случае вызов (включая оценку параметров вызова) пропускается.
[ Conditional("DEBUG") ]
public static void LogLine(string msg,string detail)
{
Console.WriteLine("Log: {0} = {1}",msg,detail);
}
public static void Main(string[] args)
{
int Total = 0;
for(int Lp = 1; Lp < 10; Lp++)
{
LogLine("Total",Total.ToString());
Total = Total + Lp;
}
}
Проблема в том, что все параметры метода должен быть оценен до вызова метода. С учетом используемого синтаксиса пути обойти это невозможно. Поскольку в C # нет настоящего препроцессора или макросов, вы не можете делать ничего вроде «LOG_DEBUG». Лучшее, что вы могли сделать, это использовать if (logger.isDebugEnable)
, как предлагается.
Единственное, что я могу придумать, - это использовать что-то вроде лямбда-выражения для задержки вычисления. Но я хотел бы предупредить вас, что это почти наверняка приведет к большему снижению производительности в конце .
internal class Sample
{
private static void Main(string[] args)
{
DelayedEvaluationLogger.Debug(logger, () => "This is " + Expensive() + " to log.");
}
private static string Expensive()
{
// ...
}
}
internal static class DelayedEvaluationLogger
{
public static void Debug(ILog logger, Func<string> logString)
{
if (logger.isDebugEnabled)
{
logger.Debug(logString());
}
}
}
Без препроцессора вы - СОЛНЕЧНО. Конечно, ничто не мешает вам использовать его перед загрузкой кода в компилятор C #.