IDE0063什么时候处置?

问题描述 投票:0回答:2

我正在尝试理解这个 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 }


c# ide refactoring c#-8.0
2个回答
74
投票
void Method() { // not relevant code using var client = new Client(); // pre code... client.Do(); // post code... }

会使此无效。

在新语法中,

;

保留在周围方法(或其他

client
范围块)的范围内。请注意,您也可以省略最外面的一对
{}
这称为 

using 声明

,文档位于 here ()

逻辑上,Dispose 发生在 
void Method() { using var client = new Client(); // pre code... client.Do(); // post code... // more code... } --> client.Dispose() is called here (at the latest)

,但优化器可能会更早执行。

    


44
投票
}

语句语法继承了其

父级的
范围。 我必须同意 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 软件包,并且

您将获得 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 或更高版本的语言。

以及将

Microsoft.Net.Compilers

添加到您的项目文件中的提议(即使 Microsoft 官方不支持)。它有效,但有警告。但对于较旧的 .NET 版本,情况似乎并非如此。因此,在旧项目上接受这些新语法提示时要格外小心!

更新:
我对旧的 NET Framework 版本触发提示的看法是错误的。罪魁祸首是旧版本(2.10.0)的

<LangVersion>8.0</LangVersion>

。这是与旧版本 Visual Studio 兼容的最后一个版本。删除该包后,不再提供提示。

© www.soinside.com 2019 - 2024. All rights reserved.