2

我正在利用 NLog 将委托而不是字符串作为日志调用的一部分的能力。例如

log.Error(()=>"I am an error which was encountered at " + DateTime.Now)

仅在启用日志记录时才评估此委托。从理论上讲,它允许更快的执行,因为委托并不总是被评估。漂亮。

当我像一个优秀的 3rd 方库消费者一样包装 NLog 记录器时,我的问题就开始了。我有一个类似的界面

public interface ILog
{
 ...        
    void Error(string errorMessage, params string[] args);
    void Error(Func<string> messageGenerator);
    void Error(Exception excepetion, string errorMessage, params string[] args);
    void Error(Exception excepetion, Func<string> messageGenerator);
 ...
}

然后像这样的实现

...

    public void Error(Func<string> messageGenerator)
    {
        //_log is an NLog logger
        _log.Error((LogMessageGenerator) messageGenerator);
    }
....

我的问题是在我的错误日志中没有对 lambdas 进行评估。我玩了一下,我认为问题在于,当 Func 首次创建时,它被创建为简单的 Func,然后当它被传递到 NLog 时,它被传入而不是 LogMessageGenerator。调用接受对象的 NLog 重载。所以我猜测当它编译 lambdas 时,C# 编译器会尝试根据上下文静态键入它们的返回值。

 //log is raw nlog logger
 log.Error(()=> "I am a terrible error"); => LogMessageGenerator
 //log is my wrapper
 log.Error(()=> "I am an even more terrible error"); => Func<string>

有什么方法可以构建我的 ILog 实现,使其仍然调用正确的 NLog 重载,而无需通过更改方法签名以采用 LogMessageGenerator 在我的界面中显式依赖 NLog?我天真地尝试将我的 Func 转换为 LogMessageDelegate 但这是不行的。

4

1 回答 1

1

尝试

public void Error(Func<string> messageGenerator)
{
    //_log is an NLog logger
    _log.Error(new LogMessageGenerator(messageGenerator));
}
于 2013-08-14T23:37:48.397 回答