Article Overview
- Background
- Pre-requisites
- Null-Coalescing Assignment
- Async Streams
- Property, Tuple, and Positional Patterns
- Summary
Background
I
have divided this whole article into 4 parts to make it easy to
understand. This article mainly focuses on three key features and
enhancements to C# 8.0:
- Null-Coalescing Assignment
- Async Streams
- Property, Tuple, and Positional Patterns
Here, I have kept all the implementation details with a complete example.
Prerequisites
- You should have basic knowledge of C#.
- It will be good if you can go through my previous parts of this series,
For your reference, I have kept all the examples in a single .cs file and uploaded it with this article for easy to use.
Null-Coalescing Assignment
Below are the key syntax improvements:
- New version introduces null-coalescing assignment operator ??=.
- Use ??= operator to assign a value of its right-hand operand to its left-hand operand only if the left-hand operand evaluates to null.
- It simplifies the common coding pattern where the variable is assigned the value if it is null.
Now, let us understand it by example.
Example 1
- int? i = 1;
- int j = 2;
- i ??= j;
- Console.WriteLine($"{i}");
Example 2
- int? variable = null;
- int expression = 5;
- if (variable == null)
- {
- variable = expression;
- }
- variable ??= expression;
- Console.WriteLine($"{variable}");
Async Streams
- For developing IoT applications this feature will be very useful where you are dealing with lots of asynchronous calls returning the data.
- It allows using ‘async’ to iterate over the collections.
Now, let us understand by example.
Example
- await foreach (var number in GenerateSequence())
- {
- Console.WriteLine(number);
- }
- public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
- {
- for (int i = 0; i < 20; i++)
- {
- await System.Threading.Tasks.Task.Delay(100);
- yield return i;
- }
- }
Property, Tuple, and Positional Patterns
Property Patterns
- Property pattern will enable you to match on properties of an object examined.
- For example, for the eCommerce website, it must compute sales tax based on the buyer's address. Sales tax amount will depend on the State property of the address.
Now, let us understand by example.
Example
- Address location = new Address();
- location.State = "MN";
- decimal salePrice = 10;
- Console.WriteLine(ComputeSalesTax(location, salePrice));
- public static decimal ComputeSalesTax(Address location, decimal salePrice) => location switch
- {
- { State: "WA" } => salePrice * 0.06M,
- { State: "MN" } => salePrice * 0.75M,
- { State: "MI" } => salePrice * 0.05M,
-
- _ => 0M
- };
- public class Address
- {
- public string State;
- }
Tuple Patterns
- It allows matching of more than one value into a single pattern matching expression.
- Some algorithms depend on multiple inputs.
- Tuple patterns allow to switch based on the multiple values which are expressed as a tuple.
Example
- Console.WriteLine(RockPaperScissors("rock", "paper"));
-
- public static string RockPaperScissors(string first, string second) => (first, second) switch
- {
- ("rock", "paper") => "rock is covered by paper. Paper wins.",
- ("rock", "scissors") => "rock breaks scissors. Rock wins.",
- ("paper", "rock") => "paper covers rock. Paper wins.",
- ("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
- ("scissors", "rock") => "scissors is broken by rock. Rock wins.",
- ("scissors", "paper") => "scissors cuts paper. Scissors wins.",
- (_, _) => "tie"
- };
Positional Patterns
- It can be used while testing a type with a Deconstructor method.
- Its syntax is very similar to tuple patterns.
Example
- Point2 obj = new Point2(1, 5);
- Console.WriteLine(GetQuadrant(obj));
-
- static Quadrant GetQuadrant(Point2 point) => point switch
- {
- (0, 0) => Quadrant.Origin,
- var (x, y) when x > 0 && y > 0 => Quadrant.One,
- var (x, y) when x < 0 && y > 0 => Quadrant.Two,
- var (x, y) when x < 0 && y < 0 => Quadrant.Three,
- var (x, y) when x > 0 && y < 0 => Quadrant.Four,
- var (_, _) => Quadrant.OnBorder,
- _ => Quadrant.Unknown
- };
- public enum Quadrant
- {
- Unknown, Origin, One, Two, Three, Four, OnBorder
- }
- public class Point2
- {
- public int X { get; }
- public int Y { get; }
-
- public Point2(int x, int y) => (X, Y) = (x, y);
-
- public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
- }
Summary
Now, I believe you will be able to implement "Null-Coalescing Assignment", "Async Streams", and "Property, Tuple, and Positional Patterns" in C# 8.0.
Previous parts of this series,