DEV Community

jeikabu
jeikabu

Posted on Originally published at rendered-obsolete.github.io on

C# 8.0 Switch and .NET 5.0

With Visual Studio 2019 released, weโ€™re counting down to .NET Core 3.0 and C# 8.0 this fall. Microsoft just announced the plan going forward: .NET 5 (coverage on VentureBeat amongst others).

.NET 5

Unless youโ€™re a long-time enthusiast of .NET, the entire ecosystem of โ€œ.NET Frameworkโ€/โ€.NET Coreโ€/โ€Monoโ€, various languages (C#/F#/etc.), and associated TLA-soup of libraries is subtle and confusing. Steering things in the same direction and unifying various sundry technologies is a goal for Fall 2020:

  • Unify .NET Framework, .NET Core, and Xamarin/Mono into single platform.
    • .NET Framework and .NET Core become single open-source framework/runtime: โ€œ.NET 5โ€.
    • Mono and CoreCLR (.NET Core runtime) as alternative โ€œruntime experiencesโ€.
  • Java interoperability on all platforms, Objective-C and Swift on some platforms.
  • Improve AOT compilation story.
    • Full AOT needed for iOS, WASM/WebAssembly, and some other platforms.
    • Partial AOT (to reduce startup time and memory usage) combined with JIT (to maximize code support for generics, reflection, etc.) useful.
    • Mono has had AOT for a while, UWP apps have .NET Native, .NET Framework has older NGEN tool.

C# 8.0 switch

Weโ€™re (most) excited about โ€œnullable reference typesโ€ (to catch some null-related runtime exceptions at compile-time), but thereโ€™s other good stuff coming in C# 8. The humble switch was upgraded with pattern matching in C# 7 and gets a few new abilities in C# 8.

Hereโ€™s the starting struct from the .NET Blog post by Mads:

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);
}
๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung ๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung

Switch expressions allow switch to โ€œreturnโ€ a value:

// Before (switch as a statement)
string Display(object o)
{
    switch (o)
    {
        case Point p:
            return $"({p.X}, {p.Y})";
        default:
            return "unknown";
    }
}
// After (switch as an expression)
string Display(object o)
{
    return o switch
    {
        Point p => $"({p.X}, {p.Y})",
        _ => "unknown"
    };
}
๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung ๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung

If the end of a switch expression is reached without making a match then an exception is thrown.

Property patterns allow you to further refine matches based on accessible fields:

// Before (switch as a statement)
string Display(object o)
{
    switch (o)
    {
        case Point p when p.X == 0 && p.Y == 0:
            return "origin";
        //...
    }
}
// After (switch as an expression)
string Display(object o)
{
    return o switch
    {
        Point { X: 0, Y: 0 } /* p */ => "origin",
        Point { X: var x, Y: var y } /* p */ => $"({x}, {y})",
        {} => o.ToString(), // `o` is non-null and not a `Point`
        null => "null"
    };
}
๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung ๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung

Positional patterns work with tuples and types that have a Deconstruct() method (like Point above, also see deconstructors):

string Display(object o)
{
    return o switch
    {
        Point(0, 0) => "origin",
        Point(var x, var y) => $"({x}, {y})",
        //...
    }
}

// General case for tuples
string DisplayXY(int x, int y, bool isValid)
    (x, y, isValid) switch {
        (_, _, false) => "invalid",
        (0, 0, true) => "origin",
        //...
    }
๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung ๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung

Overall, Iโ€™m not thrilled about XYZ switch syntax instead of switch XYZ, but these are otherwise welcome additions (especially coming from other languages with a similar feature).

For a longer write up also see this recent MSDN magazine article.

Top comments (3)

๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung
 
yaser profile image
Yaser Al-Najjar •

I hope they're going into the right path...

Cuz I feel that with the various attempts to unify things recently, it's gonna end up as a big ball of mud ๐Ÿ˜ถ

๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung
 
frothandjava profile image
Scot McSweeney-Roberts •

I'm not convinced .Net 5 makes things less subtle and confusing. Especially when it comes to cross platform support.

๐Ÿ† Live Soccer TV: jeikabu/c switch and net aa - Jadwal Siaran Langsung
 
saint4eva profile image
saint4eva •

I am loving C# 8. And I cannot wait to USE..NET 5