我试图了解C#8的简化功能:
IDE0063的“使用”语句可以简化
例如,我有:
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
方法?
答案 0 :(得分:18)
我认为您正在使用C#8(预览版),请进行检查。在较旧的C#版本中,;
会使此命令无效。
在新语法中,client
保留在周围方法(或其他{}
范围块)的范围内。请注意,您也可以省略外部()
对。
它被称为 using声明,文档为here。
void Method()
{
using var client = new Client();
// pre code...
client.Do();
// post code...
// more code...
} --> client.Dispose() is called here (at the latest)
从逻辑上讲,处置发生在}
处,但优化程序可能会更早地完成。
我注意到在// more code
块结尾之后有using
,这阻止了这种改进的出现。因此,如果您转换以下代码,将不再有歧义:
void Method()
{
// not relevant code
using (var client = new Client())
{
// pre code...
client.Do();
// post code...
}
}
输入此代码:
void Method()
{
// not relevant code
using var client = new Client();
// pre code...
client.Do();
// post code...
}
答案 1 :(得分:3)
简短的答案是,新的(可选)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
在整个方法范围内。
现在,如果原始using
块之后没有任何变化,Visual Studio将仅建议此更改,因此它在功能上是相同的。但是,如果以后添加更多代码怎么办?使用旧的范围表示法,很清楚新代码是在范围内还是在范围外。使用新语法,using
之后的所有内容都在范围内,但是可能不清楚。
罗斯林小组可能已经意识到这并不重要。与流控制语句(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),我会 do 得到这个建议,然后产生一个构建错误。 IDE不会向您显示该错误-您的项目看起来很整洁-但实际构建时会遇到两个语法错误。
在面向.NET 4.8时,如果您尝试使用C#8.0语法,则会获得友好的
CS8370 C#功能在C#7.3中不可用。请使用语言版本8.0或更高版本。
,并提供了将<LangVersion>8.0</LangVersion>
添加到您的项目文件的提议(即使Microsoft正式不支持)。需要注意的地方。但是,对于较旧的.NET版本,情况似乎并非如此。因此,在较旧的项目上接受这些新的语法提示时,请格外谨慎!
更新:我错了,旧版的NET Framework触发了提示。罪魁祸首是Microsoft.Net.Compilers
的旧版本(2.10.0)。那是与Visual Studio的旧版本兼容的最新版本。删除该程序包后,将不再提供提示。