重构:没有作用域的 using 语句,隐式的“Dispose”调用何时发生?

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

前几天我在重构一些东西,遇到了这样的事情:

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."));
    }
}

ReSharper 建议将其重构为:

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."));
}

我有点怀疑,实际上我不确定隐式 Dispose 调用何时会在第二个版本中发生。

我怎么知道?

那是 C#8 using statement,当变量本身超出范围时,scope 引用的对象将被释放。

在这种情况下,那将是在您的 Task 完成之后。

Resharper 建议 C# 8.0 using declaration 特性:

 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)

我也在想同样的事情。 using 声明在方法末尾移出范围​​,然后才被处理掉。 Microsoft docs states 以下:

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.

看起来,如果您有一个 using 语句,它会在 using 大括号的末尾释放变量,而不是仅在方法末尾释放变量的 using 声明。如果您在 watch 或 locals window 中查看它,您会立即看到它移出范围。 https://dirkstrauss.com/c-sharp-8-0-using-declarations/