26

Is there a mechanism for the new c# 8 using statement to work without a local variable?

Given ScopeSomething() returns a IDisposable (or null)...

Previously:

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

However in C# 8 with the using statement, it requires a variable name:

using var _ = ScopeSomething();

The _ here is not treated as a discard.

I would have expected this to have worked:

using ScopeSomething();
12
  • 1
    @Saeid that’s not how this feature works Commented Apr 11, 2020 at 2:40
  • 2
    @Saeid it’s a common pattern in logging and other areas to provide a sort of context or explicit scope Commented Apr 11, 2020 at 2:44
  • 1
    Thanks for explaining, if I'm not mistaken, the compiler decides the scope of the "using' statement in C# 8 based on the last usage of the disposable instance. I'm guessing with the pattern you explained, you want to do something (E.g., logging the execution) when the instance is disposed. I think with what you are proposing, the compiler supposed to dispose the instance when the method block ends. I don't think there is a way to do that in C# 8. It can be a good new feature for C# 9! Commented Apr 11, 2020 at 2:53
  • 2
    @Saeid - "The lifetime of a using local will extend to the end of the scope in which it is declared." - That's the current C# 8 implementation. No need to wait for C# 9. Commented Apr 11, 2020 at 3:16
  • 2
    Filed github.com/dotnet/roslyn/issues/43292 . Thanks for finding this issue! Commented Apr 12, 2020 at 3:28

1 Answer 1

16

There are two kinds of resource_acquisition supported by using as per the specifications: local_variable_declaration and expression.

I believe the local using in C# 8 is a shortcut to local_variable_declaration form not expression form as per the language feature proposal, where you could see:

Restrictions around using declaration:

Must have an initializer for each declarator.

This also provides the ability to use more than one resources in a single using statement as per the language specs states:

When a resource_acquisition takes the form of a local_variable_declaration, it is possible to acquire multiple resources of a given type.

So you could do:

using IDisposable a = Foo1();
using IDisposable a = Foo1(), b = Foo2(), c = Foo3();

It may be possible that the language team could add expression form support in the future versions, but for now, expression is not yet supported.

Sign up to request clarification or add additional context in comments.

4 Comments

+1 This appears to be a valid answer. I just want to point out that with the classic using statement, it has always been possible to acquire multiple resources with/without declared variable declarations. For example, using (Foo1()) using ( Foo2()) { } was/is supported with the classic using statement (assuming Foo1() and Foo2() return an IDisposable).
@AhmedAbdelhameed Not within the same using though, like using (Foo1(), Foo2()) is invalid, but using(IDisposable a = Foo1(), b = Foo2()) is valid.
They compile to the same IL, AFAICT. See this vs this.
Yes because they both valid using statements and translated as per the C# specs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.