Search code examples
c#loggingraii

Replicating C++'s RAII in C#


I'm rolling my own logger class, and want to represent the heirarchy of logs as the app moves through different phases:

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

etc.

In C++ (yes I know), I'd use RAII classlets that pushed themselves on the log stack when created, and popped off when they left the scope. You could then leave functions at any point and still have consistent logging.

Obviously in C# any variable has to be new'd, so it wouldn't be deleted until the next garbage collection cycle, and if you immediately create a new classlet, you could have an out-of-sync logger.

How would people try to solve this problem in C#? I want the logger syntax to be as unobtrusive to the current function as possible, and still support functions with multiple exit points.

The only solution I can think of off the top of my head involves closeHeirarchy() calls every return statement - and you know I'm going to miss one somewhere.


Edit: I should make it clear I'm interested mainly in how you would replicate the RAII behaviour in c#. Is there a mechanism that provides identical behaviour?


Solution

  • You can get the behavior you are asking about if you use the using statement with an IDisposable-class.

    Do something like this:

    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
      }
    }