public static void Main()
TestImprovedPatternMatching();
TestTargetTypeNewExpression();
public static void WriteHeading(string heading, string description)
Console.WriteLine("\n\n====================================================");
Console.WriteLine(heading);
Console.WriteLine(description + "\n");
public static void TestRecords()
WriteHeading("Immutable Records", "An easy way for immutable structures");
var customer1 = new CustomerRecord("Ahnold", "S1");
var customer2 = customer1 with {LastName = "S2"};
var customer1Copy = customer1;
if (customer1 != customer2)
Console.WriteLine("Customer1 is not same as Customer2");
if (customer1 == customer1Copy)
Console.WriteLine("Customer1 is same as Customer1Copy");
public record CustomerRecord
public string FirstName {get;}
public string LastName {get; set;}
public CustomerRecord(string firstName, string lastName) => (FirstName, LastName) = (firstName, lastName);
public static void TestInitOnlySetters()
WriteHeading("Init Only Setters", "Define property that can be set during class initialization, but read-only after that");
Console.WriteLine("Uncomment line 88 to see that Init Only properties can't be changed after init. Note that the error occurs in compile time.");
var customer = new CustomerWithInitName{ FirstName="Boris", LastName="Johnson", Age = 45};
public class CustomerWithInitName
public string FirstName {get; init;}
public string LastName {get; init;}
public int Age {get; set;}
public static void TestImprovedPatternMatching()
WriteHeading("Improved Pattern Matching", "Pattern matching introduced in C# 8 has been further expanded");
var customer = new Customer { FirstName = "D", LastName = "Trump", Age = 74 };
var ageGroup = customer.Age switch
> 20 and <= 50 => AgeGroup.Adult,
FiddleHelper.Dump(customer);
Console.WriteLine("\nThis customer belongs to Age Group: " + ageGroup);
public static void TestTargetTypeNewExpression()
WriteHeading("Target Type New", "Instantiating new class does not require repeating class name on right side");
Customer customer = new() { FirstName = "J", LastName = "Biden", Age = 78 };
FiddleHelper.Dump(customer);
public string FirstName {get; set;}
public string LastName {get; set;}
public int Age {get; set;}
public static void TestCovariantReturns()
WriteHeading("Covariant Returns", "Override of a method can now return a more derived return type than the method it overrides");
var customerService = new CustomerService();
Customer customer = customerService.Create();
var vipCustomerService = new VipCustomerService();
VipCustomer vipCustomer = vipCustomerService.Create();
Console.WriteLine("customer is of type: " + customer.GetType().Name);
Console.WriteLine("vipCustomer is of type: " + vipCustomer.GetType().Name);
public class VipCustomer : Customer
int NumOfBling {get; set;}
public class CustomerService
public virtual Customer Create()
public class VipCustomerService : CustomerService
public override VipCustomer Create()
return new VipCustomer();