NET 9, described by Microsoft as "the most efficient, modern, secure, intelligent, and high-performing version of .NET to date", has been released for a week now, and today I want to experience the new features with you.
NET 9 has a lot of improvements in terms of performance, security and functionality, including thousands of changes, today we will mainly experience with you our common features that have changed.
01Installation
The first thing you can do is to check if .NET9 is installed with the dotnet --list-sdks command on the command line.
There are two main ways to install, the first is by directly downloading the .NET9 SDK.
The second way is by updating the IDE Visual Studio to 17.12.0 or later, e.g. my IDE is 17.11.6 and selecting Update will do the trick, if it's an older version, such as 17.11.4 you'll need to update it twice to get it to work.
Executing the dotnet --list-sdks command again reveals that it has been successfully installed, with the following results:
02, new escape sequences
This C#13 introduces \e as the character text escape sequence for the ESC (Escape) character Unicode U+001B. Previously, \u001b or \x1b was used.
The ESC (Escape) character (ASCII code value 27, hexadecimal 0x1b) is a control character that can be used for terminal control and text formatting. It is an invisible character in its own right, and its main function is to mark the beginning of a sequence of subsequent characters that will be assigned to the terminal to perform specific actions, such as changing the text color, setting the text style, clearing the screen, moving the cursor, etc. The ESC (Escape) character is a control character that can be used for terminal control and text formatting.
Let's take an example, for example, "ESC[31m" means set the text color to red, we change ESC to escape sequence, the code is as follows:
static void Main(string[] args)
{
var colorRed = "\x1b[31m Red Text";
(colorRed); var colorRed = "\x1b[31m red text"; (colorRed)
();
}
The execution effect is as follows:
If you use the escape sequence of ESC (Escape) characters alone, it means that the characters that follow are not visible, we can use \u001b and \x1b to see the effect of the results are as follows, and found that look at the word is not displayed:
Then we change \u001b and \x1b to \u001b1 and \x1b1 and see the effect again:
From the above figure, we can see that the result of using \u001b1 is still \u001b followed by a character that cannot be seen, while after using \x1b1b1, it becomes a question mark "?". This is because the whole \x1b1 is recognized as a longer hexadecimal sequence, rather than just a control character, which creates ambiguity, so it is not recommended to use \x1b, so this time the new escape character \e, the effect is as follows.
03, implicit index access
The implicit "from end" indexing operator [^] is now allowed in object initial value setter expressions.
Let's look at an example that first creates an ImplicitIndex class and includes a Numbers property, which is an array of integers of length 5.
Now we can initialize the property Numbers when we initialize the class ImplicitIndex and use the "start at end" index operator to populate the array values.
Let's take a look at the effect in .NET8. Mouse over the error to see that older versions do not support this feature, as shown below:
NET9 on the other hand.
04The parameter enhancement of the
While previously params only supported arrays, the params parameter now supports more collection types, including Span
public static void PrintNumbers(params int[] numbers) { }
public static void PrintNumbers(params List<string> numbers) { }
public static void PrintNumbers(params HashSet<int> numbers) { }
public static void PrintNumbers(params SortedSet<int> numbers) { }
public static void PrintNumbers(params IList<int> numbers) { }
public static void PrintNumbers(params ICollection<int> numbers) { }
public static void PrintNumbers(params IEnumerable<int> numbers) { }
public static void PrintNumbers(params Span<int> numbers) { }
public static void PrintNumbers(params ReadOnlySpan<int> numbers) { }
The params keyword allows a method to take a variable number of parameters, usually a collection of parameters of a single type. parameters can usually be arrays, collections, or other methods that implement IEnumerable.
public static void PrintNumbers(params Dictionary<int, int> numbers) { }
public static void PrintNumbers(params SortedList<int, int> numbers) { }
public static void PrintNumbers(params LinkedList<int> numbers) { }
public static void PrintNumbers(params Queue<int> numbers) { }
public static void PrintNumbers(params Queue numbers) { }
public static void PrintNumbers(params Stack<int> numbers) { }
public static void PrintNumbers(params Stack numbers) { }
public static void PrintNumbers(params Hashtable numbers) { }
05Locked Objects
This update introduces a new lock type for implementing mutexes. In previous versions locking was usually done via the object type, but now there is a specialized Lock type for locking.
The new Lock type will make code cleaner, safer, and more efficient.
EnterScope replaces the underlying Monitor implementation in the new locking mechanism. It also follows the Dispose pattern of returning a ref struct, so it can be used in conjunction with using statements.
Let's take a look at the code example below:
// .NET 9 beforehand
public class LockExampleNET9Before
{
private readonly object _lock = new();
public void Print()
{
lock (_lock)
{
("We're old locks.");
}
}
}
// .NET 9
public class LockExampleNET9
{
private readonly Lock _lock = new();
public void Print()
{
lock (_lock)
{
("We are. .NET 9 new lock");
}
}
public async Task LogMessageAsync(string message)
{
using (_lock.EnterScope())
{
("We are. .NET 9 new lock,compatible withusingshare");
}
}
}
06, Generate UUID v7
We often use the Guid as the primary key in the entity, and through () can easily generate a new Guid, and the Guid generated by this method is based on the UUID fourth version of the specification generated.
Currently it has been possible to create the seventh version of the UUID through the Guid.CreateVersion7() method, the main function of this version of the UUID is to include a timestamp, the data structure is as follows:
| 48-bit timestamp | 12-bit random | 62-bit random |
This also means that v7 version of UUID can be sorted by time, which is more convenient to use in the database, while the Guid.CreateVersion7() method also has an overloaded method to receive DateTimeOffset type timestamps, which are used to create UUIDs by the specified time.
static void Main()
{
// v4 UUID
var guid_v4 = ();
// v7 UUID
var guid_v7 = Guid.CreateVersion7();
// v7 UUID with timestamp
var guid_v7_time = Guid.CreateVersion7(());
();
}
classifier for sums of money: The test method code as well as the sample source code have been uploaded to the code repository for those who are interested./hugogoos/Planner