Hello friends,
C# 8 officially got released on 23rd Sep 2019 along with .NET Core 3.0 and Visual Studio 2019 v16.3. It has several new features and enhancements to give more power to C# developers and make their day to day coding even easier.
I have started writing series of articles to go through new C# 8 features one by one to cover all the new features and enhancements. In case you have not gone through my previous articles on C# 8, you may go though as follows.
In this article, we will go through the new using declaration and read-only struct members.
New using declaration
Using keyword plays a big role in primary cleaning-up resources without explicit invocation. With C#, it has become even simpler to use and does the same job as earlier.
Let's have a look at the code below to understand the change. In the example below, both old and new using styles have been added.
- public static void ExecuteUsingFunction()
- {
- List<string> messages = new List<string>(); messages.Add("Hello readers of Learning C# 8!!"); messages.Add("How are you!!"); ExecuteOldUsingFunction(messages); ExecuteNewUsingFunction(messages);
- }
- static void ExecuteOldUsingFunction(IEnumerable<string> lines)
- {
- using (var file = new StreamWriter("file.txt"))
- {
- foreach (string line in lines)
- {
- if (!line.Contains("C# 8"))
- {
- file.WriteLine(line);
- }
- }
- }
- }
-
- static void ExecuteNewUsingFunction(IEnumerable<string> lines)
- {
- using var file = new StreamWriter("file.txt"); foreach (string line in lines)
- {
- if (!line.Contains("C# 8"))
- {
- file.WriteLine(line);
- }
- }
-
- }
As you can see in the method ExecuteNewUsingFunction that the new using is intuitive to work with.
In an old using statement, the file is disposed of when the closing brace associated with the using is reached however in a new pattern, the file is disposed of when the closing brace for the method is reached as that's the end of the scope for file declaration. In both types of using statement, the compiler generates the call to Dispose() to clean up resources hence they are considered equivalent.
Read-only struct members
You can now apply readonly to any struct members. This is an extension of adding to readonly as a struct level. It indicates that the member does not alter the data or modify the state. This feature helps the compiler in not creating a defensive copy of a variable.
Let's take an example below to see it in action.
- public struct Distance
- {
- public double X { get; set; } public double Y { get; set; }
- public double PointDistance => Math.Sqrt(X * X + Y * Y);
- public readonly override string ToString() =>
- $"({X}, {Y}) is {PointDistance} from the origin point";
- }
The above code results in a warning message as following.
Compiler generates a warning because of ToString property as it accesses the property PointDistance is not created as readonly.
To fix the warning, just put the readonly on PointDistance property as follows.
- public readonly double PointDistance => Math.Sqrt(X * X + Y * Y);
By adding readonly to PointDistance property you may have realized that the readonly modifier is necessary even on get properties as the compiler doesn't assume get accessors do not modify state. This feature lets you specify your design intent clearly so that compiler can make necessary optimizations.
Summary
In this article, we have learned about new using declaration and read-only struct members and why are they required. We have gone through to understand that how new using declaration simplifies the syntax. read-only struct members is also a new addition in struct and helps designing intent more clearly. Clearly these new features are the great value additions for developers.