C# 8 中不使用变量的 using 语句

18

新的C# 8中是否有不需要本地变量就能工作的using语句机制?

如果ScopeSomething()返回一个IDisposable(或null)......

以前:

using (ScopeSomething())
{
    // ...
}

然而,在 C# 8 中使用 using 语句时,需要一个变量名:

using var _ = ScopeSomething();

这里的_并不被视为废弃。

我本来以为这样会起作用:

using ScopeSomething();

1
@Saeid,这不是该功能的工作方式。 - Daniel A. White
2
@Saeid 在日志记录和其他领域中,提供一种上下文或明确范围的常见模式。 - Daniel A. White
1
谢谢您的解释,如果我没记错的话,在C# 8中,“using”语句的作用域是由编译器根据可处理实例的最后一次使用来决定的。我猜测根据您所解释的模式,您想在实例被处理时执行某些操作(例如记录执行)。我认为根据您的建议,编译器应该在方法块结束时处理实例。我不认为在C# 8中有这样做的方法。这可能是C# 9的一个很好的新功能! - Saeid
2
@Saeid - “using” 本地变量的生命周期将延伸到它被声明的作用域的结束。这是目前 C# 8 的实现。无需等待 C# 9。 - Enigmativity
2
已提交至 https://github.com/dotnet/roslyn/issues/43292 。感谢您发现此问题! - Julien Couvreur
显示剩余7条评论
1个回答

11
根据 规范using 支持两种类型的 resource_acquisition: local_variable_declarationexpression
我认为 C# 8 中的本地 using 是 local_variable_declaration 形式的快捷方式,而不是 expression 形式,根据 语言特性提案 可以看到:

使用声明的限制:

每个声明符必须有一个初始化器。

这也提供了在单个 using 语句中使用多个资源的能力,正如语言规范所述:

resource_acquisition 采用 local_variable_declaration 的形式时,可以获取给定类型的多个资源。

所以你可以这样做:
using IDisposable a = Foo1();
using IDisposable a = Foo1(), b = Foo2(), c = Foo3();

也许语言团队未来的版本中会增加对expression表单的支持,但现在还不支持。


+1 这似乎是一个有效的答案。我只想指出,使用经典的 using 语句,一直可以获取多个资源,无论是否声明变量声明。例如,using (Foo1()) using ( Foo2()) { } 在经典的 using 语句中得到支持(假设 Foo1()Foo2() 返回一个 IDisposable)。 - 41686d6564 stands w. Palestine
1
@AhmedAbdelhameed 不过不在同一个 using 语句块中,例如 using (Foo1(), Foo2()) 是无效的,但是 using(IDisposable a = Foo1(), b = Foo2()) 是有效的。 - weichch
据我所知,它们编译成相同的IL。请参见此处此处 - 41686d6564 stands w. Palestine
是的,因为它们都是有效的 using 语句,并且按照 C# 规范进行了翻译。 - weichch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接