Srikanth Technologies

What's New In C# 8.0

The following are the new features introduced in C# 8.0.

C# 8.0 is supported from .NET Core 3.x.

Default Methods in Interface

It is possible to create a method with code (default method) in Interface starting from C# 8.0.

This feature allows authors of interface to add methods in interface without breaking existing implementation. However, these methods are accessible only by using interface object reference.

interface ICounter
{
  void Inc();
  void Dec();
  // Default method 
  string Author()
  {
    return "Srikanth Pragada";
  }
}

class MyCounter : ICounter
{
  private int value = 1;
  public void Dec()
  {
      this.value--;
  }
  public void Inc()
  {
      this.value += 1;
  }
}
class InterfaceMethods
{
   static void Main(string[] args)
   {
      ICounter c = new MyCounter();
      c.Inc();
      Console.WriteLine(c.Author());
   }
}

Switch Expression

Switch expressions enable you to use more concise expression in switch. We don't have to use case and break statements. The following example shows how to get discount based on product code.

int disrate = code switch
 {
    1 => 10,
    2 => 20,
    3 => 25,
    _ => 5    // Rest of the values - similar to default 
 };

The above switch decides the discount rate based on variable code. Note that variable code comes before switch keyword.

Tuple Patterns

It is also possible to use Tuple patterns, where we can compare more than one value in switch statement using tuple syntax.

// Find out discount rate based on code and qty 
int disrate = (code,qty) switch
{
    (1,1) => 10,
    (1,2) => 20,
    (2,1) => 15,
    (2,2) => 30,
    (_,_) => 5
};

Comparing one expression with multiple values

It is also possible to use multiple values in a single case and combine them using logical operators as follows:

int days = month switch
{
  2 => 28,
  4 or 6 or 9 or 11 => 30,
  _ => 31
};
  

We find out the number of days in a given month using switch. If month is 4,6,9, or 11 then we return 30.

Using Declaration

When a variable declaration is preceded by using keyword, it means the variable must be disposed after the current block is completed.

static void Main(string[] args)
{
   using var f = new StreamReader("names.txt");
   // use f to read data
   // f is automatically disposed at the end of block 
} 

Null-Coalescing Assignment - ?? and ??=

Operator ?? returns value of left-hand operand if it isn't null; otherwise, it evaluates right-hand operand and returns its value.

The most import point to note is, it doesn't evaluate right-hand operand if left-hand operand evaluates to not-null.

The operator ??= is used to assign value to a variable only when variable is null otherwise it doesn't change the value of variable.

int? v = null;

v ??= 10;  // assigns 10 as v is null
v ??= 20;  // doesn't change value of v as it already has value 

Console.WriteLine(v);  // prints 10

String name = null;
Console.WriteLine(name ?? "Unknown" );   // prints Unknown

name = "C#";
Console.WriteLine(name ?? "Unknown");   // prints C#

Indices and Ranges

It is possible to access elements in a sequence using two new operators - ^ (caret) and .. (2 dots) while using index.

Operator ^ followed by a number that specifies the index is relative to end of the sequence.

Operator .. specifies range of indices.

Here are some examples:

var names = new string[] { "C#", "Java", "JavaScript", "Python" };

Console.WriteLine(names[^1]);     // Python
Console.WriteLine(names[^4]);     // C#

// First two entries
foreach (var s in names[0..2])    // C# and Java
     Console.WriteLine(s);

// Last two entries 
foreach (var s in names[^2..])    // JavaScript and Python
     Console.WriteLine(s);

// Strings also support ^ and ..
Console.WriteLine( "Hello"[^1]);   // o
Console.WriteLine("Hello"[0..4]);  // Hell