5 things we should know in C# 10

In C# 10, I have found these 5 features useful to write code prettier and faster.

Constant interpolated strings

String interpolation introduced in C# 6, it made our job easy by providing the simplified and convenient way to apply formatting in to a string.

An interpolated string is usually a combination of strings and an expression. On the run time, the expression is executed and the resultant string value will be added in the placeholder.

But there is a limitation, we cannot interpolate the constant string but it is allowed in C# 10.

const string Name = "World";
const string Greeting = $"Hello {Name}";

Extended property patterns

Extended Property Patterns help us to improve the readability of code in accessing the child property from the parent property. Prior to C#10, child property were inaccessible at the same level as it involves nested level.

C# 8

{ParentProperty: { ChildProperty: Value}}

C# 10

{ParentProperty.ChildProperty: Value}

Global using

Global Using allows us to declare namespace/directive globally and it will available to all the files in the application. It helps us to declutter the code and keep it clean by prevent the duplication of declare same namespace in multiple classes/files. So we can put commonly used libraries and namespaces in one file and used across our project.

For example

global using system;

We don’t want to explicitly declare the above namespace in any file its needed and it can be declared in the common file.

File scoped namespace

File scoped namespace allows to declare a namespace for a entire file. After the namespace, we can declare and define the following types : Class, Struct, Delegate, Enum and Interface.

In earlier versions

namespace App
{
  public class MyApp
  {
  }
}

In C# 10

namespace App;
public class MyApp
{
}

It limits to allow only one namespace per file. It is used to simplify the boilerplate code.

ASSIGNMENT and declaration in the same deconstruction

In earlier version of C#, it allows to assign value to existing variable or declare new variable in the deconstruction but we can’t do both at the same time . In C#10, this restriction has been overcome and we can declare both in the single deconstruction.

Before C# 10

// Declare new variable
(string name, string email) = var customer;

// Assign value to existing variable
string name;
string email;
(name, email) = customer;

In C# 10

// Allows both new variable declaration and assign to existing variable

string name;
(name, string email) = customer;

OTHER C#10 Improvements

  • Lambda Expression : Lambda expressions are more similar to methods and local functions. They can have a natural type and also apply attributes to lambda expressions.
var lambda = [DebuggerStepThrough]() => "Hello World";
  • Structure Type: struct types can have parameterless constructor and intialise the instance field or property at its declaration
public struct Customer
{
  // Parameterless constructor with property intialization
  public Customer()
  {
     Name = "Smith";
  }
  // Initialization of the property at its declaration
  public string Name { get; set; } = "Mike";
}
  • Null Checking: Simplifies the null check and throw error in a single liner.

In early version

string name;
if (name is null)
{
  throw new ArgumentNullException(nameof(name));
}

In C# 10

ArgumentNullException.ThrowIfNull(name);

There are lot more features released in C# 10 but found the above features to make our code more readable and productive.

Happy C’Sharping 🙂

Records – C# 9 new feature

As a part of C# 9, Microsoft has released quite a notable features and in this article, I am going to quickly run through an interesting feature called “Records”.

What is Records?

Records bridge the gap and limitations which currently exists between class and struct types in C#.

Classes are more efficient to use around but their equality is determined by their underlying reference rather than its associated values. Whereas, Structs get value semantics when determining equality but have to be copied when passed around.

Records enables to have value semantics while still being passed by reference.

Okay. Now, let see how can we implement record in C#.

      public record Order
      {
        public int Id { get; init set; }

        public string Status { get; init set; }

        public bool IsPaid { get; init set; }
      }

One of the key difference between the regular classes and records is that records are intended to be immutable, so its state will never change.

Whenever the object’s state change, we create a copy of the object, updating the members that have changed rather than changing the original record directly.

How to update records?

In order to update the record, instead of mutating their data, we need to create a new instance but with different values using with expression.

For an example, if we want to update the status property of Order records means, we need to do as the followings.

var updatedOrder = order with { Status = "Delivered" };

Interesting point here, unless regular reference types, status of the order object is not changed, only the new created updatedOrder will have a new status value. But still the order object will hold its previous value.

Equality

Usually if we compare two instances of the same class which contains the same values, they will not be considered equal. They are equal, only if they share the same underlying reference.

In terms of Records, they are rather than compared by object’s reference, they are compared by values. So we can say, Records are not defined by their identity buy by their contents.

Why do we need records?

  • It is immutable. When we are dealing with external service by sending or received data or simply data transfer within an application, data transfer objects are the perfect example for records.
  • In testing point of view, we could compare the two records instance by their value rather by their instance.
  • It will guarantee , no changes has been happened while sending or receiving the data subsequently as the value of the record instance is preserved.

Hope it gives some idea about the Records and its usage. I believe, its quite an interesting feature to use in C#9.

Happy C’Sharping 🙂