C#'s GitHub page has a long list of tantalizing ideas, some of which are still being discussed. If you want to know what new features are included in C#10, wait until the new version is released in November. Alternatively, you can follow the C#team's showcase of their favorite features. At the recent Microsoft Build conference, C#lead designer Mads Torgersen revealed some of the work currently underway. Here are five new features that will be available in the next version of the language.

1. global using
C#'s source code file usually imports a bunch of namespaces at the beginning of it. Here is a code snippet for a normal ASP.NET Web application:
using LoggingTestApp.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace LoggingTestApp
{
public class Startup
{
...
}
}
There is nothing special about how this code is written. Previously, importing namespaces allowed us to quickly understand which libraries a class was using. Today, however, this is just a bunch of code that has to be written and no one has to read.
C#10 introduces a new pattern that allows you to use the keyword global to define namespace imports for the entire project. The recommended practice is to place global imports in a separate file (one for each project), which can be named usings.cs or imports.cs. The content is roughly as follows:
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.HttpsPolicy;
global using Microsoft.AspNetCore.Identity;
global using Microsoft.AspNetCore.Identity.UI;
global using Microsoft.EntityFrameworkCore;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
Then you can simplify the original document:
using LoggingTestApp.Data;
using Serilog;
namespace LoggingTestApp
{
public class Startup
{
...
}
}
Visual Studio highlights duplicate namespaces (i.e. namespaces imported in both global and local files). Although this is not an error, removing duplicate namespaces reduces the amount of code and focuses attention on the special namespaces that specific files are using.
2. file-wide namespace
C#10 provides another way to simplify code: declare file-scoped namespaces. The file-wide namespace is automatically applied to the entire file and does not require indentation.
In other words, write it like this:
namespace LoggingTestApp
{
public class Startup
{
...
}
}
Can become:
namespace LoggingTestApp;
public class Startup
{
...
}
If you add another namespace block to a file that uses a file-range namespace, a nested namespace is created:
namespace Company.Product;
// This block creates the namespace Company.Product.Component
namespace Component
{
}
C#designers believe this change will clean up waste of horizontal space (just as global using cleaned up waste of vertical space). The overall goal is to make the code shorter, narrower, and more concise. But these changes can also make it easier for newcomers to learn C#. Combining global using with file-scoped namespaces allows you to create a Hello World console application in just a few lines of code.
3. null parameter check
In the spirit of reducing boilerplate code, C#provides a very good new feature: null parameter checking. You must have written methods that need to check for null values. For example, the following code:
public UpdateAddress(int personId, Address newAddress)
{
if (newAddress == null)
{
throw new ArgumentNullException("newAddress");
}
...
}
Nowadays, you just add "!!" to the end of the parameter name, C#will automatically add this empty parameter check. The above code can be simplified to:
public UpdateAddress(int personId, Address newAddress!!)
{
...
}
Now, if you pass a null value to Address, an ArgumentNullException will be automatically thrown.
This detail may seem trivial, but it is actually a very simple and valuable way to optimize the language. A large number of studies have shown that the causes of program errors are often caused by the repeated occurrence of very easily avoidable errors, not because the concepts in the code are too complex, but because reading the code is tiring and human attention is limited. Reducing the amount of code reduces the time required to review code, the cognitive load required to process code, and the possibility of ignoring certain errors due to reduced attention.
4. required attribute
Previously, we could only use class constructors to ensure that objects were created correctly. Nowadays, we often use more lightweight constructs, such as the automatically implemented attribute in the following record:
public record Employee
{
public string Name { get; init; }
public decimal YearlySalary { get; init; }
public DateTime HiredDate{ get; init; }
}
When creating instances of such lightweight objects, we may use the object's initialization syntax:
var theNewGuy = new Employee
{
Name = "Dave Bowman",
YearlySalary = 100000m,
HiredDate = DateTime.Now()
};
But what if some properties in your object are required? You can add a constructor as before, but then you need to add more boilerplate code. In addition, copying values from a parameter to a property is another easy-to-understand but common mistake.
The keyword required introduced by C#10 can eliminate such problems:
public record Employee
{
public required string Name { get; init; }
public decimal YearlySalary { get; init; }
public DateTime HiredDate{ get; init; }
}
As a result, you cannot create an Employee without setting the Name attribute.
5. Keyword field
Over the years, the C#team has made a lot of effort to simplify code by automatically implementing attributes. The Employee record above is a good example of this, which uses the get and init keywords to declare three immutable attributes. Data is stored in three private fields, but these fields are created automatically without human intervention. And you will never see these fields.
The attributes that are automatically implemented are great, but they are just as good as they are. When automatically implemented attributes are not available, you must add supporting fields to the class and write normal attribute methods, just like going back to C#2. However, C#10 provides a keyword field that can automatically create supporting fields.
For example, suppose you want to create a record to process initial property values. In the following code, we make some modifications to the Employee class to ensure that the HiredDate field only contains date information from the DateTime object (no time information):
public record Employee
{
public required string Name { get; init; }
public decimal YearlySalary { get; init; }
public DateTime HiredDate{ get; init => field = value.Date(); }
}
This code is very neat, simple, and close to declarative.
You can use the keyword field to access fields in get, set, or init. Also, you may need to verify an attribute just like you would verify an attribute in a normal class:
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
if (value.Trim() == "")
throw new ArgumentException("No blank strings");
_firstName = value;
}
}
You can use fields to verify automatically implemented properties:
public string FirstName {get;
set
{
if (value.Trim() == "")
throw new ArgumentException("No blank strings");
field = value;
}
}
Essentially, as long as you don't need to modify the data type of the attribute, you don't need to declare your own supporting fields.
6. summary
Of course, there are definitely more than these five new features in C#10. There are also a few changes to expressions, and one controversial change: defining static members in interfaces. We can only wait patiently.
Overall, the development focus of C#10 is clear, that is, reducing the amount of code, providing more convenience, and reducing the burden on developers.
Author: Matthew MacDonald
Original link: https://www.example.com
Translator: Crescent Moon
Editor in charge: Ouyang Shuli
Produced by: CSDN (ID: CSDNnews)
Statement: This article was translated by CSDN. Please indicate the source for reprinting.