Biz*_*han 14 c# ide refactoring c#-8.0
我试图了解此C#8简化功能:
IDE0063的“使用”语句可以简化
例如,我有:
void Method()
{
using (var client = new Client())
{
// pre code...
client.Do();
// post code...
} --> client.Dispose() was called here.
// more code...
}
Run Code Online (Sandbox Code Playgroud)
IDE告诉我可以using通过编写以下代码来简化此语句:
void Method()
{
using (var client = new Client());
// pre code...
client.Do();
// post code...
// more code...
}
Run Code Online (Sandbox Code Playgroud)
我不明白它是如何工作的以及它如何决定我不再using是变量。更具体地说,它什么时候调用client.Dispose方法?
Nei*_*ett 35
简短的回答是新的(可选)using语句语法继承了其父级的作用域。
我必须同意 OP 的观点,这是 C# 8.0 中一个非常令人困惑的变化,原因有很多。
在历史上,using始终与其它块一样,一个范围操作(if,switch等)。就像if,using语句的范围是下一行或代码块。
所以写这样的东西是完全有效的:
using (var client = new Client())
client.Do();
Run Code Online (Sandbox Code Playgroud)
这意味着client仅在单个语句的范围内,这对于单行操作非常有用,例如触发没有返回值的 SQL 存储过程。
但现在我们也有:
using var client = new Client();
client.Do();
Run Code Online (Sandbox Code Playgroud)
这根本不是一回事;client仍然在整个方法的范围内。
现在,如果原始using块之后没有任何内容,Visual Studio 只会建议此更改,因此它在功能上是相同的。但是如果以后添加更多代码呢?使用旧的范围表示法,很清楚新代码是在范围内还是在范围外。使用新语法,后面的所有内容using都在范围内,但这可能不清楚。
Roslyn 团队可能认为这并不重要。与流控制语句(if等)不同,你真的关心你的对象是否在多几行代码的范围内?可能不是。但就像所有事情一样,这取决于。
在某些方面,这是一种改进,因为它清楚地说明了“实例化此对象并Dispose()在它超出范围时调用”。对象总是破坏,垃圾回收,当他们走出去的范围(即方法结束),但这并不意味着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 版本触发提示。罪魁祸首是旧版本 (2.10.0) 的Microsoft.Net.Compilers. 这是与旧版本 Visual Studio 兼容的最后一个版本。删除该包后,不再提供提示。
Hen*_*man 14
我认为您使用的是C#8(预览版),请检查一下。在较早的C#版本中,这;将使其无效。
在新语法中,client停留在周围方法(或其他{}作用域块)的作用域中。请注意,您也可以省略外部对()。
这称为使用声明,文档在此处。
void Method()
{
using var client = new Client();
// pre code...
client.Do();
// post code...
// more code...
} --> client.Dispose() is called here (at the latest)
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,Dispose发生在,}但优化程序可能会更早地完成。
我注意到,// more code在程序using段结束之后,阻止了这种改进的出现。因此,如果您转换以下代码,将不再有歧义:
void Method()
{
// not relevant code
using (var client = new Client())
{
// pre code...
client.Do();
// post code...
}
}
Run Code Online (Sandbox Code Playgroud)
变成这段代码:
void Method()
{
// not relevant code
using var client = new Client();
// pre code...
client.Do();
// post code...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1717 次 |
| 最近记录: |