What's new in C# 8? (Part One)

As of right now, the second preview of C# 8 is out and it seems that the new features for the most part involve switch case enhancements, using declaration, static local functions, and disposable ref structs. Previously the features such as asynchronous streams and indices and ranges were introduced in the first preview of C# 8.  However, since a single line of code speaks a thousand words I will jump right into the example snippets to make it clear how it will be like to use these new features.


Switch Expressions

Given the following enum:

public enum Rainbow

You can directly assign a switch case to a function in the following way: 

public static RGBColor FromRainbow(Rainbow colorBand) =>
    colorBand switch
        Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
        Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
        Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
        Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
        Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
        Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
        Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
        _              => throw new ArgumentException
                             (message: "invalid enum value", 
                              paramName: nameof(colorBand)),

Property Pattern

Properties of a specific object can also take part in the switch case pattern very much similar to the previous example. Assuming that the `location` object given in the following example comes with a property named `State`, switch cases can now be used in C# 8 the following way:

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

Tuple Pattern

Another cool feature that helps write a cleaner code is the new tuple pattern which allows for passing positional values to cases of a switch statement. The following example explains it the best:

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 Parren

Previously introduced in C# 7.x, an accessible `Deconstruct` method could be used for breaking types into tuples. Now, it can be integrated with a switch case statement. Given the following type:

public class Point
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y) => (X, Y) = (x, y);

    public void Deconstruct(out int x, out int y) =>
        (x, y) = (X, Y);

Assuming that we need to recognize the corresponding quadrant for a given point, the following code can be now written in C# 8:

public enum Quadrant
static Quadrant GetQuadrant(Point 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

End of Part One

Image placeholder

About The Author

I was grabbed by the gravity of computer science in 1994 and I’ve been accelerating in my orbit ever since. In this system, my mission is to accomplish the unachievable. It is to fly above and beyond conventions and to craft code which docks with any rapidly revolving mechanism. From this vantage point everything looks so spectacular.