我正在尝试理解这个 C# 8 简化功能:
IDE0063 'using'语句可以简化
例如我有:
void Method()
{
using (var client = new Client())
{
// pre code...
client.Do();
// post code...
} --> client.Dispose() was called here.
// more code...
}
IDE 告诉我可以通过编写以下内容来简化此
using
语句:
void Method()
{
using (var client = new Client());
// pre code...
client.Do();
// post code...
// more code...
}
我无法理解它是如何工作的以及它如何决定我不再是变量。更具体地说,它到底什么时候调用
using
方法?编辑
client.Dispose
块结束后添加
// more code
可以防止出现这种改进。所以如果你转换下面的代码就不会再有歧义了:using
进入这段代码:
void Method()
{
// not relevant code
using (var client = new Client())
{
// pre code...
client.Do();
// post code...
}
// more code does not exist
}
void Method()
{
// not relevant code
using var client = new Client();
// pre code...
client.Do();
// post code...
}
会使此无效。
在新语法中,;
保留在周围方法(或其他
client
范围块)的范围内。请注意,您也可以省略最外面的一对 {}
。这称为 using 声明
逻辑上,Dispose 发生在
void Method()
{
using var client = new Client();
// pre code...
client.Do();
// post code...
// more code...
} --> client.Dispose() is called here (at the latest)
,但优化器可能会更早执行。
}
语句语法继承了其
父级的范围。 我必须同意 OP 的观点,由于多种原因,这是 C# 8.0 中一个非常令人困惑的变化。
从历史上看,
using
始终与其他块(
using
,if
等)一样在范围内运行。与 switch
一样,if
语句的范围是代码的下一行或下一个块。 所以写这样的东西是完全有效的:
using
这意味着
using (var client = new Client())
client.Do();
仅在单个语句的范围内,这对于单行操作非常有用,例如触发没有返回值的 SQL 存储过程。
但现在我们还有:
client
这根本不是一回事;
using var client = new Client();
client.Do();
仍然在整个方法的范围内。
现在,仅当原始
client
块之后没有任何内容时,Visual Studio 才会建议进行此更改,因此它在功能上是相同的。但是如果稍后添加更多代码怎么办?使用旧的范围符号,新代码是否在范围之内或之外就非常清楚了。使用新语法,
using
之后的所有内容都在范围内,但这可能不清楚。罗斯林团队可能认为这并不重要。与流程控制语句(
using
等)不同,您真的关心您的对象是否在多几行代码的范围内吗?可能不会。但就像所有事情一样,这取决于情况。
在某些方面,这是一种改进,因为它清楚地表明:“实例化该对象并在它超出范围时调用
if
。”当对象超出范围(即方法结束)时,对象总是会被销毁并被垃圾收集,但这并不意味着调用了
Dispose()
。将 Dispose()
添加到局部变量声明只是实现这一目标的一种方法。
最后,这是大
,如果您的目标是 .NET Framework,那么您可能并没有真正使用 C# 8.0。你可能认为你是;我做到了。您可能正在运行 Visual Studio 2019 16.3+。您甚至可能安装了最新版本的
using
软件包,并且 说
在我的测试中,当我以 .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 或更高版本的语言。
以及将Microsoft.Net.Compilers
更新:我对旧的 NET Framework 版本触发提示的看法是错误的。罪魁祸首是旧版本(2.10.0)的
<LangVersion>8.0</LangVersion>
。这是与旧版本 Visual Studio 兼容的最后一个版本。删除该包后,不再提供提示。