Search code examples
c#.net-coredisposeusing-statement

Refactoring: using statement without scope, when does the implicit `Dispose` call happen?


I was refactoring some the other day, I bumped into something like that:

public async Task<Result> Handle(CancelInitiatedCashoutCommand command, CancellationToken cancellationToken)
{
    using (_logger.BeginScope("{@CancelCashoutCommand}", command))
    {
        return await GetCashoutAsync(command.CashoutId)
            .Bind(IsStatePending)
            .Tap(SetCancelledStateAsync)
            .Tap(_ => _logger.LogInformation("Cashout cancellation succeeded."));
    }
}

and ReSharper suggested to refactor it as:

public async Task<Result> Handle(CancelInitiatedCashoutCommand command, CancellationToken cancellationToken)
{
    using var scope = _logger.BeginScope("{@CancelCashoutCommand}", command);
    return await GetCashoutAsync(command.CashoutId)
        .Bind(IsStatePending)
        .Tap(SetCancelledStateAsync)
        .Tap(_ => _logger.LogInformation("Cashout cancellation succeeded."));
}

I am a bit skeptical, actually I am not sure when the implicit Dispose call will happen with the second version.

How can I know?


Solution

  • Resharper suggests C# 8.0 using declaration feature:

     public async Task<Result> Handle(CancelInitiatedCashoutCommand command, 
                                      CancellationToken cancellationToken)
     {  
        using var scope = ...;
        ...
     } // <- scope will be Disposed on leaving its scope (here on Handle method's scope)