将Func重新分配给特定的委托人

本文关键字:委托人 分配 Func 新分配 | 更新日期: 2023-09-27 18:27:38

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

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

只有在启用了日志记录的情况下才会评估此委托。理论上,它允许更快的执行,因为并不总是对委托进行评估。Nifty。

当我像一个好的第三方库消费者一样包装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时,它只是作为一个Func而不是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,但这是不可能的。

将Func重新分配给特定的委托人

尝试

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