Natalie Perret
Natalie Perret

Reputation: 9007

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?

Upvotes: 10

Views: 1545

Answers (3)

Dread P. Rob the II
Dread P. Rob the II

Reputation: 83

I was wondering the same thing. The using declaration moves out of scope at the end of the method, and is only disposed of then. Microsoft docs states the following:

the file is disposed when the closing brace for the method is reached. That's the end of the scope in which file is declared.

It would seem that if you have a using statement, it would dispose of the variable at the end of the using brace, as opposed to the using declaration that only disposes of the variable at the end of the method. If you view this in the watch or locals window, you will immediately see it move out of scope. https://dirkstrauss.com/c-sharp-8-0-using-declarations/

Upvotes: 4

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186793

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)

Upvotes: 6

Johnathan Barclay
Johnathan Barclay

Reputation: 20363

That is a C#8 using statement, and the object referenced by scope is disposed when the variable itself goes out of scope.

In this case, that would be after your Task has completed.

Upvotes: 5

Related Questions