Article Overview
- Background
- Pre-requisites
- Null-Coalescing Assignment
- Points
- Example
- Async Streams
- Points
- Example
- Property, Tuple, and Positional Patterns
- Points
- Example
- 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,
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; // C# 1..7
- }
- variable ??= expression; // C# 8
- 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.
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.
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,
- // other cases removed for brevity...
- _ => 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.
- 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,

RyderPosted Feb 7, 2020, 5:48 AM
Nice one...
RyderPosted Feb 7, 2020, 5:43 AM
Good article.
mohd arifPosted Oct 16, 2019, 10:10 AM
Nice One, Thanks
Arvind KatariaPosted Oct 10, 2019, 1:09 AM
Nice article
Dhruvik SathvaraPosted Oct 10, 2019, 12:22 AM
Nice article...