C# 8: Using statement
Simplify your using statements.
C# 8.0 Series
Want to read my other posts about C# 8?
- C# 8: nullable reference types.
- C# 8: Indexes and Ranges.
- C# 8: Using statement revisited!
Prerequisites & Setup
You will need Visual Studio 2019 and .NET Core 3.0 SDK to try out the new using statement syntax. We need to modify the .csproj file to enable C# 8.0 as well:
A small example
Did you liked my Car class from the previous C# 8 posts? No? That’s okay, I will anyway use it again ;). This time the whole code is little more advanced because we will encrypt and decrypt our car.
I hope you aren’t overwhelmed by this - don’t worry I will explain it as good as I can. On the first few lines we create an instance of a Car and generate a secret key and initialization vector for the encryption and decryption.
Please be aware: Never store a secret (passwords, useranmes, keys, ...) in your code! Seriously, it isn't secure in any way!
After that we encrypt the car and put the result into a memory stream named outStream. Then we need to rewind the stream to position zero to ensure we are able to read (decrypt) it. The decrypt function is returning a new instance of the car that must hold the same information, as the first instance. Otherwise we messed up our encrypt or decrypt function (btw. that would be a good candidate for a Unit-Test).
Everyone who reads attentively spotted already that my using statement looks incomplete for prior C# versions (<=7.3). Are you familiar with the concept of stream-chaining? When not, then I show you something new combined with the new using syntax. Let’s see the Encrypt method used above:
Here, we take the outStream parameter and pass it to the CryptoStream to have everything written to the stream encrypted. The cryptoStream is passed to the DeflateStream to get the stream compressed as well. Finally we use the BinaryFormatter to serialize what ever instance we pass in as obj.
Beside the encryption, stream-chaining and serialization - important is that almost everything is disposable here and ultimately shows how much cleaner the new capability of the using statement looks like. But still maintaining disposing all instances as soon they left the scope. The comments are reflecting the order of how they get disposed.
This new capability doesn’t change the framework or the runtime - it is a pure language feature. Roslyn emits the rest of the using statement for us! IL-Spy reveals this:
For completeness the Decrypt method:
Closing words
This feature is small, but has enough impact to be worth writing and thinking about it. I love it and I’m sure you will use it too. It removes some tedious steps when we have local disposable resource as shown above especially when we forget the using statement. Writing less code usually increases also readability and this is important. Code is less written than read and therefore it is critical for our colleagues and ourself.