DEV Community

Cover image for 4 Features Every Developer Must Know in C# 9.0
Suresh Mohan for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com

4 Features Every Developer Must Know in C# 9.0

C# is already a language for developers. Still, Microsoft is making every effort to improve the experience for programmers when using C#. In the release of .NET 5.0, not only were frameworks unified, Microsoft also rolled out C# 9.0 with some groundbreaking new features.

The following are the features that most impressed me in this version:

  • Init-only setters
  • Records
  • Top-level statements
  • Pattern matching

In this blog, I will discuss each of them.

Init-only setters

Previously, instantiating objects with immutable data had to be done in the constructor by passing values as parameters. Now, it has been simplified to use the syntax init. It initailizes the immutable data during object creation which allows developers to create immutable properties.

Refer to the following code examples.
Usual format:

class Customers
{
    public int CustomerId { get; }
    public string CustomerName { get; set; }

    public Customers(int customerId)
    {
        CustomerId = customerId;
    }

    static void Main(string[] args)
    {
        var customers = new Customers(1045)
        {
            CustomerName = "Tyson"
        };

        //customerid cannot be set as the property is immutable.
        customers.CustomerId = 1099;
    }
}
Enter fullscreen mode Exit fullscreen mode

Using init-only setters:

class Customers
{
    public int CustomerId { get; init; }
    public string CustomerName { get; set; }

    static void Main(string[] args)
    {
        var customers = new Customers()
        {
            CustomerId = 1045,
            CustomerName = "Tyson"
        };

        //customerid cannot be set as the property is immutable.
        customers.CustomerId = 1099;
    }
}
Enter fullscreen mode Exit fullscreen mode

Records

Records allow us to handle an object like a value rather than a collection of properties. As the records mostly deal with immutable states, they are flexible and also best used for data, rather than functionalities.

In the following example, I have used a with expression to create a new record that inherits values from another record.

Usual format:

class SalesOrder
{
    public int OrderId { get; init; }
    public string ProductName { get; init; }
    public int Quantity { get; init; }

    static void Main(string[] args)
    {
        SalesOrder order = new SalesOrder { OrderId = 1, ProductName = "Mobile", Quantity = 2 };

        //now we need to change "ProductName"
        SalesOrder newOrder = new SalesOrder { OrderId = order.OrderId, ProductName = "Laptop", Quantity = order.Quantity };
    }
}
Enter fullscreen mode Exit fullscreen mode

Using records:

public record SalesOrder
{
    public int OrderId { get; init; }
    public string ProductName { get; init; }
    public int Quantity { get; init; }

    static void Main(string[] args)
    {
        SalesOrder order = new SalesOrder { OrderId = 1, ProductName = "Mobile", Quantity = 2 };

        //using with expression
        SalesOrder newOrder = order with { ProductName = "Laptop" };
    }
}
Enter fullscreen mode Exit fullscreen mode

Top-level statements

This feature helps software developers exclude unwanted code from a program. Top-level statements can replace all the boilerplate code (repeating code) with a single line.

Refer to the following code examples.
Usual format:

using System;

namespace CSharp9
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Welcome to Syncfusion!");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Using top-level statements:

using System;

Console.WriteLine("Welcome to Syncfusion!");
Enter fullscreen mode Exit fullscreen mode

To be more precise, we can use:

System.Console.WriteLine("Welcome to Syncfusion!");
Enter fullscreen mode Exit fullscreen mode

Pattern matching

If you’re a regular user of C#, you might know that pattern matching is one of the features introduced in C# 7.0. It helps us extract information from a value. C# 9.0 contains many new patterns, but here we are going to discuss relational and logical patterns.

Relational patterns

These patterns work with relational operators such as <, <=, >, and >=.

Logical patterns

These patterns work with logical operators like and, or, and not.

Refer to the following code example.

public class SalesOrder
{
    public int OrderId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public int TotalCost { get; set; }

    public double GetTotalCost() => TotalCost switch
    {
        500 or 600  => 10,
        < 1000 => 10 * 1.5,
        <= 10000 => 10 * 3,
        _ => 10 * 5
    };
}

class CSharpFeatures
{
    static void Main(string[] args)
    {
        SalesOrder newOrderforCustomer1 = new SalesOrder() { OrderId = 1, ProductName = "Camera", Quantity = 1, TotalCost = 5000 };
        newOrderforCustomer1.GetTotalCost();
        SalesOrder newOrderforCustomer2 = new SalesOrder() { OrderId = 2, ProductName = "Pen", Quantity = 1, TotalCost = 500 };
        newOrderforCustomer2.GetTotalCost();
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

With these features, C# 9.0 helps programmers easily work with data (records), shape code (pattern matching), and reduce code (top-level statements). If you want to know more about the new features in the C# 9.0 official release, please read this documentation.

If you have any concerns or need any clarification, please mention them in the comments section below. You can also reach us through our support forums, Direct-Trac, or feedback portal.

If you like this blog post, we think you’ll like the following articles too:

Latest comments (1)

Collapse
 
amsmart profile image
Emmanuel Oluwagbemiga Adebiyi (Smart)

Nice article