将Func重新转换为特定代表

时间:2013-08-14 21:54:32

标签: c# nlog

我正在利用NLog的能力来获取委托代替字符串作为日志调用的一部分。例如

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

仅在启用日志记录时才评估此委托。从理论上讲,它可以更快地执行,因为代理并不总是被评估。俏皮。

当我将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);
    }
....

我的问题是,在我的错误日志中,lambda没有被评估。我玩了一下,我认为问题在于,当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实现,这样它仍然可以通过更改方法签名来获取LogMessageGenerator来调用NLog的正确重载而不在我的接口中对NLog进行显式依赖?我天真地尝试将我的Func转换为LogMessageDelegate,但这是不行的。

1 个答案:

答案 0 :(得分:1)

尝试

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