What Features Does Version 10 Of C # Provide Programmers With?

What Features Does Version 10 Of C # Provide Programmers With?

Version 10 Of The C # Programming Language Was Released Along With Version 6 Of The .NET Framework. In The New Version, Relatively Important Functionalities Have Been Provided To Programmers, And Some Previous Capabilities Have Been Improved To Make The Readability Of This Popular Language Even More Than Before. 

This article will take a brief look at the most important ones.

Null Parameter Checking

Null Reference Exception is one of the most troublesome application errors. Developers have to check method inputs to prevent this error, but the new feature makes the process easier and the code more readable. The following syntactic combination is currently used to check the emptiness of a parameter:

public MyFunction (int id, SomeClass newObject)


if (newObject == null)


throw new ArgumentNullException (“newObject”);


// Code Here


In the above method, an object called the new object of type SomeClass is assigned to the MyFunction parameter. The plan should not work if the object is not initialized (empty). C # 10 simplifies this evaluation process. Enough, two characters !! Add a parameter to the end of the name.

public MyFunction (int id, SomeClass newObject !!)


// Code Here


The new object is automatically checked for emptiness in the code snippet. If the evaluation is positive, an ArgumentNullException error is generated, which can be managed without any problems.

Required Properties

Experienced programmers do not use a complex constructor in their programs and prefer to use simple builders. In other words, they prefer to refer to the values ​​directly in the fields. Programmers use lightweight constructs to build objects, such as the following code snippet:

var Myconstructor = new MyClass


Title = “Hi Everyone”

Category = “.NET”,

ReleaseDate = DateTime.Now ()


In version 10 of C #, the keyword Required was introduced about attributes. However, sometimes attributes need to be initialized, but developers may forget this. In this case, when creating a class, we can define a mandatory field that if the said field is not set when sampling the course, a compilation time error will occur.

public class MyClass


public required string Title {get; init;;

public string Category {get; init;;

public DateTime ReleaseDate {get; init;;


Global Using feature

Typically, programmers use the using command at the beginning of the sources they write in C #, accompanied by the namespaceNamespaces are the classes, methods, and data objects programmers need to write their code—for example, System, System.

Linq, System.Collections.Generic, etc., are present in almost all projects, and files are written in the C # scripting language . .NET and C # Sharp development teamIn version 10 introduced the Global Using feature. This feature allows programmers to use the term Global Using to import a namespace instead of using the Using command.

What is the difference between the new command and the previous command? If you use Global Using in one of the project files, you do not need to use the same Using twice in other project files. More precisely, the above command is scalable and can be extended to other files.

Developers can use Global Using in one of the leading project files, such as the Program.cs file, to extend the feature to other files. If you are looking for custom programming, we suggest creating a file called GlobalNamespace.cs in the project and putting all the Using commands in it so that you do not have to repeat the orders.

global using System;

global using System. Linq;

global using System.Collections.Generic;

Developers can use Using and Global using in a file simultaneously. Global Using can also use to import static classes. The syntactic composition of this work is as follows:

global using a static System.Console;

Feature Implicit Using

Projects developed with .NET version 6 are equipped with Implicit Using. Developers can enable or disable this feature. If this feature is enabled in a project, it adds some project-based uses by default. For example, the following uses are automatically added to all project files for console applications.

// <auto-generated />

global using global:: System;

global using global:: System.Collections.Generic;

global using global:: System.IO;

global using global:: System. Linq;

global using global:: System.Net.Http;

global using global:: System.Threading;

global using global:: System.Threading.Tasks;

As you can see, this feature is fully functional. Developers can use the following methods to activate the above component:

Go to the Project Properties section in Solution Explorer in Visual Studio. You will see an option called Implicit global using, which can be enabled or disabled by activating the checkboxes.

The second method is to open the project settings file called .csproj file format and enable the ImplicitUsings tag value (Enbale). To disable the above feature, just set the value of the label to Disable.

<Project Sdk = ”Microsoft.NET.Sdk”>


    <OutputType> Exe </OutputType>

    <TargetFramework> net6.0 </TargetFramework>

    <ImplicitUsings> enable </ImplicitUsings>

    <Nullable> enable </Nullable>



If you would like to know what Uses have been added to the project automatically, open the project and go to Obj \ Debug \ Net6.0. In this path, you will see a file called GlobalUsings.g.cs that contains the Uses.

The compiler automatically creates this file for projects developed on .NET 6 and has the above feature enabled. If you plan to add other options to the default Uses, you should add the following tag to the setting tags called .csproj.


    <Using Include = ”System.Numerics” />


The Numerics namespace is added to the default items in the code snippet above.

Fixed interpolation strings

(Constant interpolated strings)

This feature allows variables and computational expressions to be appended to strings in a clearer and more readable way. Traditionally, programmers use the positive (+) operator or the String class Format method to join strings. For example, if we want to create a new string by adding the two variables firstName and lastName, we need to do the same thing:

var FirstName = “Hamid Reza”;

var LastName = “Taebi”;

var Firstattach = FirstName + ““ + LastName;

var Secondattach = string.Format (“{0} {1}”, FirstName, LastName);

With the new Interpolated Strings feature, we place the $ character before the unique string and enter the variable’s name or computational operation in parentheses.

var OldMethod = $ ”{FirstName {{LastName}”;

As you can see, the Interpolated Strings feature improves string formatting and code readability, allowing you to do the integration process with less coding. However, this feature has received a significant update. Before C # 10, programmers could not use the Interpolated Strings feature to insert a return value into string constants. The output had to be entered in a variable. From now on, programmers can set the return value of Interpolated Strings to a string constant. This feature is called Constant Interpolated Strings.

private const string Myfirstname = “Hamid Reza”;

private const string Mylastname = “Taebi”;

private const string NewMethod = $ ”{Myfirstname} {Mylastname}”;

Note that only string-type constants can be interconnected through the above method, making it possible to put a return value in a string constant. Therefore, if you use this technique in conjunction with other types, you will encounter an error message.

Lambda Expression changes in Cisharp 10

One of the most powerful C # programming language keywords is the var keyword. Var allows the compiler to recognize the type of a variable based on the values ​​assigned to a variable. It is not necessary to explicitly define the type of the variable. Prior to the release of version 10, C # Sharp compiler with a code snippet similar to var MyDelegate = () => Console.WriteLine (“Hello”)Encountered because it could not recognize the Delegate type, giving an error message. To solve this problem, programmers had to specify the type of Delegate.

Action MyDelegate = () => Console.WriteLine (“Hello”);

In version 10, the Inferred Delegate Type feature has been added so that the compiler can detect the Delegate type. Note that the phrase on the right, called Lambda Expression, must be understandable to the computer. For example, suppose you want to use the var keyword and use a syntax such as var multiple = x => x * x; You use. The compiler cannot detect type x, generating an error message. To solve the problem of the above command, we must declare type x exactly.

var multiple = (int x) => x * x;

Another important issue to consider is the type of Delegate output. If you want to write a Delegate that returns two different types, the compiler can not detect the output type and will show an error message. For example, consider the following command

var result = (int x) => x> 10? 40: “forty”;

In the above command, the output type based on the value of x is of the integer or string type. The compiler cannot detect the output type and displays an error message. In the new version, programmers can specify the type of Lambda Expression output. Before entering the lambda expression, they select a style that defines the output type of the lambda expression. Now, if we write the above command as follows, there is no problem:

var result = object (int x) => x> 10? 40: “forty”;

In the above command, we specified that the output type of the lambda expression is of type Object. Object type indicates that the output can be of any type. In this case, the compiler is open to detecting the type of Delegate output. This feature is called the Lambda Return Type.

Defining a property on a lambda expression is another feature added to lambda expressions. Like ordinary methods, it can add a lambda expression to a property called a “lambda expression.” For example, suppose we want to add an Attribute Obsolete to a lambda expression. The syntax for doing this is as follows:

var result = [Obsolete] object (int x) => x> 10? 40: “forty”;

Added two new types, DateOnly and TimeOnly

DateTime is an old programming world that the ancients were quite familiar with DateTime. As you know, the DateTime type holds time and date information. For example, if we call the DateTime.Now command, it shows the current date and time. Before releasing version 10 of C #, if we only needed the date or time, we had to select the type we wanted explicitly. In version 10, two new styles, DateOnly and TimeOnly, have been added so that date and time can use separately. The syntactic composition of the new kinds used is as follows:

DateOnly Justdate = DateOnly.FromDateTime (DateTime.Now);

TimeOnly Justtime = TimeOnly.FromDateTime (DateTime.Now);

Console.WriteLine (Justdate);

Console.WriteLine (Justtime);

As you can see, the date and time values ​​are stored in two separate objects. Here Justdate only keeps the date, and Justtime only saves the time. The most significant advantage of adding these two new types for programmers is the more excellent compatibility of date and time types in SQL Server, as they are more similar in terms of data.

Improved struct performance

Structures have changed in the writing of 10 syllables. One of these changes is the definition of a constructor without a parameter in the struct. Before version 10, it was impossible to define a constructor without a parameter, and developers had to specify at least one parameter for a struct. This feature is called “Parameterless Struct Constructors.” To better understand the above concept, pay attention to the following code snippet:

struct Point


    public Point ()


        X = 0;

        Y = 0;


    public double X {get; set; }

    public double Y {get; set; }


As you can see, the Point structure has a parameterless constructor. You must set all its properties inside the constructor. Otherwise, you will encounter the following error message. The compiler declares that Y is not initialized in the following error message.

Auto-implemented property ‘Point. Y’ must be fully assigned before control is returned to the caller.

Another feature that has been added to structures with version 10 is called struct field initializers. The above attribute allows the property to be set when defining it. Developers can use the following combination for this purpose:

public double X {get; set; } = 0;

The above solution prevents the compiler from showing an error message by initializing all the structural properties. A subtle point to note when using the above technique is to use semicolons (;) at the end of the command.

Another interesting feature added to the structures is called This feature allows you to make a copy of the object made of the structure and change some of its properties if necessary.

var p1 = new Point (12, 13);

var p2 = p1 with {Y = 49};

In the code snippet above, object p1 is defined with values ​​of 12 for X and 13 for Y. In the second line, the with keyword is used to make a copy of p1, and then the value of Y is changed 49. And in this case, the object p2 is created with a new deal.

Essential changes to Property Pattern in version 10

introduce Property Pattern in version 8 of C # . Developers could use the above feature to evaluate objects with values ​​of related properties, which played an essential role in easier readability and comprehension of code. For example, suppose you have two classes, Person and Car, and you want to write a method and check if a person has red machines. To do this, we report the following code snippet:

public class Person


    public string Name {get; set; }

    public Car? Car {get; set; }


public class Car


    public string Color {get; set; }


static bool HasPersonRedCar (Person person) => person is {Car: {Color: “Red”}};

Next, we create an object of class Person and call the HasPersonRedCar method on the new thing.

var ali = new Person ()


    Name = “Alex”,

    Car = new Car


        Color = “Red”,



Console.WriteLine (HasPersonRedCar (Alex));

The above code snippet returns true.

As you can see, the Car checks the property of the Person object and returns the True value if the Color property is equal to Red. Otherwise, the False value is returned. In the above model, we have to write a pair of open and closed braces to check the value of each property. This feature has been improved in writing ten syllables to make the code more straightforward and readable. Based on the new terms, the above code snippet can be rewritten as follows:

static bool HasPersonRedCar (Person person) => person is {Car.Color: “Red”}

As you can see, the parentheses around the Color property have been removed, and the dot operator has been used.