Using, using, using with C# 8 (2024)

C# has different meanings for the using keyword. One is the using directive to import types from namespaces, and to create aliases to types. The second meaning is the using statement as a convenient syntax on using the IDisposable interface. With C# 6, also the using static directive was added to allow accessing static class members without the need to specify the type. C# 8 now adds another variant to the using keyword – one that is related with the using statement, the using declaration. I think I will replace most of my usages of the using statement to use the new using declaration instead. This article does not step into the using directive, but gives you information about the new C# 8 feature using declaration.

Using, using, using with C# 8 (1)

Disposing Resources

First, let’s start with the traditional using statement and the class AResource which implements the IDisposable interface:

public class AResource : IDisposable{ public void UseIt() => Console.WriteLine($"{nameof(UseIt)}"); public void Dispose() => Console.WriteLine($"Dispose {nameof(AResource)}");}

The using statement can be used to reference a variable or the result from a method, and at the end of the scope defined by the using statement, the Dispose method gets invoked:

private static void TraditionalUsingStatement(){ using (var r = new AResource()) { r.UseIt(); } // r.Dipose is called}

Behind the scenes, the compiler creates code using try/finally to make sure Disposeis also called when an exception is thrown:

private static void TraditionalUsingStatementExpanded(){ var r = new AResource(); try { r.UseIt(); } finally { r.Dispose(); }}

With the new C# 8 using declaration, the code with the using statement can be simplified. Curly brackets are no longer needed. At the end of the scope of the variable r (which is here the end of the method), the Dispose method is invoked. Here, the compiler also creates a *try/finally block to make sure Dispose is called if errors occur.

private static void NewWithUsingDeclaration(){ using var r = new AResource(); r.UseIt();}

That’s a small feature of C# 8, but we need to get a little bit more into details.

Disposing Multiple Resources

Using multiple resources, I’ve often seen code like this with multiple nested using statements:

private static void TraditionalMultipleUsingStatements(){ using (var r1 = new AResource()) { using (var r2 = new AResource()) { r1.UseIt(); r2.UseIt(); } }}

Because the body of the outer using statement just consists of a single statement – the inner using statement, it is possible to simplify the code. This looks better than the previous one, and it stays better also if more than two resources need to be disposed:

private static void TraditionalMultipleUsingStatements2(){ using (var r1 = new AResource()) using (var r2 = new AResource()) { r1.UseIt(); r2.UseIt(); }}

Next let’s do the same with the new using declaration. The following code is even shorter compared to the previous one – no matter how many resources you need to dispose:

private static void NewMultipleUsingDeclarations(){ using var r1 = new AResource(); using var r2 = new AResource(); r1.UseIt(); r2.UseIt();}

Using Scopes

What if a resource should be disposed before the method ends? You just need to add a separate scope using curly brackets. When the variable is out of scope, the resource is disposed:

private static void UsingDeclarationWithScope(){ { using var r1 = new AResource(); r1.UseIt(); } // r1 is disposed here! Console.WriteLine("r1 is already disposed");}

What can’t be done with the using declaration

Is there a reason to not use the using declaration, and keep the using statement?

In case you’ve a method returning a disposable, such as the method GetTheResource,

public static AResource GetTheResource() => new AResource();

and you don’t need a variable of this type, you just need to make sure the resource returned is disposed – with the using statement this code is possible:

private static void TraditionalResourceReturned(){ using (GetTheResource()) { // do something here } // resource is disposed here}

If you try to do the same with the using declaration, you’ll get multiple compilation errors – all in the same code line:

private static void NewResourceReturned(){ using GetTheResource(); // do something here} // resource is disposed here
  • CS1001: Identifier expected
  • CS1528: Expected ; or = (cannot specify constructor arguments in declaration)
  • CS1003: Syntax error, ‘[‘ expected
  • CS1003: Syntax error, ‘]’ expected

Probably a future version of the compiler results in a different compiler error.

The reason is that the using declaration requires a variable for the scope. In case you don’t need the variable afterwards, there’s an easy fix – just use _ for the variable name, and ignore it:

private static void NewResourceReturned(){ using var _ = GetTheResource(); // do something here} // resource is disposed here

Summary

It’s just a small feature of C# 8, but it will change the code in many places. Currently I don’t see a reason to stay with the old using statement. I think I’ll switch to the new using declaration with all my code. The number of curly brackets are reduced, but it can still be seen easily where a resource is disposed. The number of code lines is reduced using the name using declaration.

If you’ve read this far, consider buying me a coffee which helps me staying up longer and writing more articles.

Using, using, using with C# 8 (2)

Interesting Links for this article:

Complete code sample

Other C# 8 articles:

Async Streams with C# 8

C# 8 Proposal for Async Streams

Proposal: IAsyncEnumerable.WithCancellation Extension Method

C# 8: Indexes and Ranges

C# 8: Pattern matching extended

C# 8: No more NullReferenceExceptions – What about legacy code?

More information on C# and programming .NET Core applications is in my book Professional C# 7 and .NET Core 2.0, and in my workshops.

Enjoy learning and programming!

Christian

Using, using, using with C# 8 (3)

Published by

Christian Nagel

Microsoft MVP for Developer Technologies, software architect, developer, book author, trainer and consultantView all posts by Christian Nagel

Using, using, using with C# 8 (2024)

References

Top Articles
Latest Posts
Article information

Author: Rev. Porsche Oberbrunner

Last Updated:

Views: 6172

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Rev. Porsche Oberbrunner

Birthday: 1994-06-25

Address: Suite 153 582 Lubowitz Walks, Port Alfredoborough, IN 72879-2838

Phone: +128413562823324

Job: IT Strategist

Hobby: Video gaming, Basketball, Web surfing, Book restoration, Jogging, Shooting, Fishing

Introduction: My name is Rev. Porsche Oberbrunner, I am a zany, graceful, talented, witty, determined, shiny, enchanting person who loves writing and wants to share my knowledge and understanding with you.