简短的回答是新的(可选)using 语句语法继承了它的 父级 范围。
我必须同意 OP 的观点,即这是 C# 8.0 中一个非常令人困惑的变化,原因有很多。
从历史上看,using 一直像其他块一样使用作用域(if、switch 等)。和if 一样,using 语句的范围是代码的下一行或块。
所以写这样的东西是完全有效的:
using (var client = new Client())
client.Do();
这意味着client 仅在单个语句的范围内,这对于单行操作非常有用,例如触发没有返回值的 SQL 存储过程。
但现在我们也有:
using var client = new Client();
client.Do();
这根本不是一回事; client 仍然在整个方法的范围内。
现在,Visual Studio 只会在您原来的 using 块之后没有任何内容的情况下建议此更改,因此它在功能上是相同的。但是,如果稍后添加更多代码怎么办?使用旧的范围表示法,新代码是在范围内还是在范围外是非常清楚的。使用新语法,using 之后的所有内容都在范围内,但这可能不清楚。
Roslyn 团队可能认为这并不重要。与流控制语句(if 等)不同,您真的关心您的对象是否在范围内保留更多代码行吗?可能不是。但就像所有事情一样,这取决于。
在某些方面,这是一种改进,因为它清楚地表明,“实例化这个对象并在它超出范围时调用Dispose()。”当对象超出范围(即方法结束)时,它们总是被销毁并收集垃圾,但这确实 not 意味着调用了Dispose()。将using 添加到局部变量声明中只是实现这一目标的一种方式。
最后,这是大,如果您的目标是 .NET Framework,那么您可能并没有真正使用 C# 8.0。
你可能认为你是;我做到了。您可能正在运行 Visual Studio 2019 16.3+。您甚至可能安装了最新版本的 Microsoft.Net.Compilers 软件包,说您正在获得 C# 8.0,对吗?但你不是。默认情况下,.NET Framework 的上限为 C# 7.3。
在我的测试中,当我以 .NET 4.8 为目标时,Visual Studio 很智能,不会提供 C# 8.0 建议。但是,如果我以旧版本 (4.7.2) 为目标,我确实会收到此建议,然后会生成构建错误。 IDE 不会向您显示该错误 - 您的项目看起来很干净 - 但您在实际构建时会遇到两个语法错误。
当面向 .NET 4.8 时,如果您尝试使用 C# 8.0 语法,您会得到友好的
CS8370 C# 功能在 C# 7.3 中不可用。请使用 8.0 或更高版本的语言。
并提议将<LangVersion>8.0</LangVersion> 添加到您的项目文件中(即使微软官方不支持)。它有效,但有警告。但对于较旧的 .NET 版本,情况似乎并非如此。因此,在旧项目中接受这些新语法提示时要格外小心!
更新:关于触发提示的旧 NET Framework 版本我错了。罪魁祸首是Microsoft.Net.Compilers 的旧版本(2.10.0)。这是与旧版本 Visual Studio 兼容的最后一个版本。删除该包后,不再提供提示。