使用新的C# 8 Using声明语法,第二个连续using语句的包含范围是什么?
简短回答
在C# 8之前,如果有一系列的using语句,例如:
using(var disposable = new MemoryStream())
{
using(var secondDisposable = new StreamWriter(disposable))
{}
}
会扩展成类似以下内容(来源):
MemoryStream disposable = new MemoryStream();
try {
{
StreamWriter secondDisposable = new StreamWriter(disposable);
try{
{}
}
finally {
if(secondDisposable != null) ((IDisposable)secondDisposable).Dispose();
}
}
}
finally {
if(disposable != null) ((IDisposable)disposable).Dispose();
}
我知道还有另外两种可能的扩展,但它们大致都是这样的。
在升级到 C# 8 后,Visual studio 提供了一个代码清理建议,但我不确定它是否是等效的建议。
它将上述连续的 using 语句转换为:
using var disposable = new MemoryStream();
using var secondDisposable = new StreamWriter(disposable);
对我来说,这将第二个作用域更改为与第一个相同的作用域。在这种情况下,它可能会巧合地以正确的顺序处理流,但我不确定是否要依赖这种幸运的巧合。
明确一下VS要求我做什么:首先转换内部(因为内部仍包含在外部的范围内是有意义的)。然后转换外部(因为在方法的作用域中仍有意义)。这两个清理的结合是我感到好奇的地方。
我也认识到我的想法可能有些错误(甚至非常错误),但根据我今天的理解,这似乎不正确。我的评估中缺少什么?我错了吗?
唯一能想到的就是,在声明语句后面的所有内容中插入了某种隐式作用域。
Dispose
的调用也会发生,这才是我应该强调的。你在问题中表达的关注是关于处理发生的时间,而不是变量的生命周期。如果那让你感到困惑,我很抱歉。 - Eric LippertDispose
而不是作用域本身。 - Justin Blakley