【发布时间】:2020-04-04 16:33:35
【问题描述】:
前几天我正在重构一些东西,我遇到了这样的事情:
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 调用。
我怎么知道?
【问题讨论】:
-
using var scope = ... ;表示在离开Handle范围时scope将是Disposed -
所以基本上包含该语句的方法。
-
你看过the documentation吗?如果是这样,有什么不清楚的地方?顺便说一句,您总是可以通过实现自己的测试类
public class TestDispose : IDisposable { public void Dispose(){ Console.WriteLine("disposing"); }}来测试它,以查看何时调用输出。 -
对于诸如日志记录范围和事务之类的事情,如果范围仍然用块明确指示,代码可能会更清晰,因为通常不命名日志记录范围。
using var很有用,如果从功能上讲,您并不真正关心资源何时被释放,只要它发生(例如SqlConnection)。在所有情况下,Dispose时刻都是确定性的,但对于using var,当它不是特别重要时,可以不说范围。当然,这是主观的,这就是 Resharper 坚持建议的原因。 -
我确实检查了文档,但它看起来很奇怪,感觉很不对劲。我自己也检查过,是的,在调用 dispose 之后,但我不确定编译器是否可以在其他一些情况下更改重写(和隐式 Dispose 调用)
标签: c# .net-core dispose using-statement