在C#中复制C ++的RAII

时间:2009-01-23 17:33:34

标签: c# logging raii

我正在滚动我自己的记录器类,并希望在应用程序经历不同阶段时代表日志的层次结构:

log start
    loading
        loaded 400 values
    processing
         couldn't process var "x"

在C ++中(是的,我知道),我会使用RAII类在创建时将自己压在日志堆栈上,并在它们离开作用域时弹出。然后,您可以在任何时候离开函数,并且仍然具有一致的日志记录。

显然在C#中,任何变量都必须是新的,因此在下一个垃圾收集周期之前不会被删除,如果你立即创建一个新的classlet,你可能会有一个不同步的记录器。 / p>

人们如何尝试在C#中解决这个问题?我希望记录器语法尽可能不引人注目,并且仍然支持具有多个出口点的函数。

我能想到的唯一解决方案是closeHeirarchy()调用每个return语句 - 你知道我会在某个地方错过一个。


编辑:我应该说清楚我主要对如何在c#中复制RAII行为感兴趣。是否存在提供相同行为的机制?

3 个答案:

答案 0 :(得分:5)

如果您将using语句与IDisposable类一起使用,则可以获得您所询问的行为。

做这样的事情:

public class LogContext: IDisposable
{
  private readonly Logger _logger;
  private readonly string _context;

  public LogContext(Logger logger, string context){
    _logger = logger;
    _context = context;
    _logger.EnterContext(_context);
  }

  public void Dispose(){
    _logger.LeaveContext(_context);
  }
}

//...

public void Load(){
  using(new LogContext(logger, "Loading")){
    // perform load
  }
}

答案 1 :(得分:3)

OffTopic:如果您希望“记录器语法尽可能不引人注目”,您可能希望在记录器完成后查看面向方面编程。 但也许你应该采取一个简短的痛苦路线,并使用任何可用的伟大记录器(log4Net,NLog,System.Trace甚至Spring.Commonlogging)。

答案 2 :(得分:1)

System.Diagnostics.Trace值得一看。例如,它支持缩进级别等内容。 log4net项目也值得一试。