.NET Core 3.0: A Close Look for Developers

Before we plunge into .NET Core, it’s worth revisiting some of .NET’s dense, tangled history. Twenty years ago, Microsoft was preparing the .NET framework for launch; in 2001, it produced the first beta of .NET 1.0, with the first “official” version following a year later. Since then, Microsoft has engaged in continual upgrade cycles; by September 2019, .NET Framework 4.8 was released. 

That will be the last .NET Framework version, at least under that name. There may be a minor version (e.g., 4.8.1), but no 4.9. Next year, .NET 5 (without Framework or Core) will appear, and it will unify .NET Framework, .NET Core and Mono.

The interesting thing about .NET Core is that it’s open-source; unlike the .NET Framework, multiple versions can be installed side-by-side. This makes it easier to update and add new features without breaking applications. The .NET Framework just isn’t flexible, and changes can break things; for many developers, evolution in a new direction might prove a very good thing. 

Mono and .NET Core

.NET Core was introduced in 2014 (and released in 2016) to let developers write code for .NET running on Windows, Linux and Mac. At that time, it was already possible to do this with Mono, a non-Microsoft equivalent of .NET that was launched not long after .NET appeared. Over the last five years, you’ve had both ways to write code for Linux, Mac and Windows: either the Mono C# compiler or the .NET Core one. Curiously, Mono generated .exe, while .NET Core generated applications as DLLs. With .NET 3.0, the compiler now produces .exe. 

In 2016, Microsoft bought Xamarin, the company that has been driving Mono’s development since 2011. The last three years has seen a gradual convergence of platforms. Unity (the game engine) and Xamarin (the cross-platform mobile development system) both use Mono, for instance. 

Certainly Miguel de Icaza, the founder of Mono and Xamarin, appears to be in no great rush to converge class libraries in a way that avoids code duplication (and multi-platform divergence), as this answer suggests

It’s likely that .NET 4.8 will continue to support existing applications. There are still features in the .NET Framework that haven’t been ported to .NET Core, such as WinForms and WPF (though those are promised, albeit still limited to Windows). Also, WCF (Windows Communication Framework) and original ASP.NET aka WebForms will not migrate to .NET Core. 

What’s New in .NET Core 3.0?

As releases go, there are a number of minor features. These include desktop applications using WinForms or WPF (but only on Windows), IEEE Floating-point parsing and formatting improvements, high-performance built-in JSON support, HTTP/2 support, TLS 1.3/OpenSSL 1.1.1 on Linux, improved garbage collection, and ARM64 Linux support. 

The main feature is C# 8.0. Microsoft has published a full list of what’s in it, but I’ll focus on a few of my favorite ones.

Tuple Patterns

These let you perform what I call multi-dimensional switch statements. The following example shows how the new code works for Rock, Paper, Scissors with a “get” property. Note the use of ‘_’ to handle the non-matching comparisons. So, all values of first or second that don’t match the six listed cases become a “tie.” 

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"
    };

Using Declarations

This cleans up the syntax for usingso that variables are disposed correctly with less indentation and braces. 

{
  using var file1 = new StreamReader("File1.txt");
  using var file2 = new StreamWriter("File2.txt");  
  // do stuff
 }

When ‘file1’ and ‘file2’ go out-of-scope after ‘do stuff,’ they are disposed. With files, this also means closed.

The Biggest Change: New Types Index and Range

Both are additions to the System namespace. System.Index represents an index in a sequence and can work from the start or end. This type is implicitly converted to/from an integer. You can use the Carat (^) to index a sequence from the end.

int[] myArray = new int[4] { 1, 2, 3, 4 };
int lastElement = myArray[^1]; // = 4

The ^value is equal to sequence.length – value, so ^1 in the example above is 4-1 = 3 and myArray[3] is 4. Using the example above, you can get a slice of an array like this:

int [] myArray1 = myArray[0..2];  // 0,1
int [] myArray2 = myArray[1..^0]; // 2,3,4

Note: The value after the two dots (‘..’) is the end index, after the end of the array. When you declare a 10-size array, the index starts at 0 and runs to 9; 10 is the index after the end. With MyArray2, the ^0 is the same as the end index – 0 = 4. The last value in the array is ‘myArray2[3],’ or more generally for any array, ‘a.’ The last value is always ‘a[^1];’. 

This can be confusing. In a 4-element array, only elements 0 to 3 exist. Element4 doesn’t, and yet ^0 refers to this element. Think of referring to a non-existing element as more of a convention.

The Null-Coalescing Assignment Operator

C# had the ?? (null-coalescing operator) for many years. It lets you specify a default value to return if the main value is ‘null.’ New in C# 8 is the assignment operator ??=.

It lets you replace this…

  if (lefthand== null) {
    lefthand = righthand;

…with this:

  lefthand ??= righthand;

Note that “righthand” will not be evaluated if “lefthand” is not null.

Conclusion

Here’s a good example of the rapidity of .NET Core changes: Version 3.1 is scheduled for November 2019. This is a LTS (Long Term Support) version, so it will last at least three years.

If you want to try .NET Core 3.0, the easiest way is to download from this page, or if you have Visual Studio 2019 Community, run the installer (on the individual components, tick ‘.NET Core 3.0’). 

For those with an eye on the future, you’ve only another four years until .NET 8 appears in November 2023! Keep that in mind.