alt text

C# 9.0 went to General Availability on the 10th of Nov 2020.

I’ve listed below the parts which I like and have decided to do this blog post early and add to it as updates happen and I learn more.

Super interesting times!

C# 9.0 on the record by Mads Torgersen is the official release post of C# 9.0

Visual Studio 16.8 includes .NET 5.0 - notice the rename drop of Core from .NET Core 3.1

Top-level programs / statements

MS Blog link

R# giving my red squiggles so I have to get R# Early Access Program with the version on the 11th of Nov 2020 being R# 2020.3 EAP 6

JetBrains blog link

using System;

// very nice!
Console.WriteLine("Hello World!");

The compiler creates a Program class with an entry point on Main under the hood.

  • Only 1 entry point per project is allowed
  • async / await is allowed
  • types at the bottom

I’m doing bits of ETL quite often - lets see if it can help.

using System;
using System.Collections.Generic;
using Dapper;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using CsvHelper;

using var db = GetOpenConnection();

// Clear down db first (using Dapper)
db.Execute("DELETE FROM Actors");

// 1.Extract Actors
var actors = LoadActorsFromCsv();
Console.WriteLine($"Total Actors imported from csv is {actors.Count}"); // 98,690

// 2.Load
foreach (var actor in actors.Take(50))
    var sql = @"
        INSERT Actors
        VALUES (@actorid, @name, @sex)";

    db.Execute(sql, actor);

// a test async query
var someActors = await db.QueryAsync<Actor>(@"
    SELECT TOP 10 * 
    FROM Actors 
    ORDER BY Name DESC");

foreach (var someActor in someActors) 
    Console.WriteLine($"{someActor.actorid} {} {}");

// local function using CsvHelper to read a csv
List<Actor> LoadActorsFromCsv()
    using var reader = new StreamReader("..\\..\\..\\..\\data\\actors.csv");
    using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
    csv.Configuration.Delimiter = ";";
    return csv.GetRecords<Actor>().ToList();

// a local function to help Dapper
IDbConnection GetOpenConnection()
    //var connStrng = @"Server=.\;Database=IMDBChallenge;Trusted_Connection=True;MultipleActiveResultSets=true";
    var connStrng = @"Server=(localdb)\mssqllocaldb;Database=IMDBChallenge;Trusted_Connection=True;MultipleActiveResultSets=true";
    var connection = new SqlConnection(connStrng);
    return connection;

// types must be defined at the bottom of the file
class Actor
    // favouring the simplest data type string in this load
    // until I understand the data (ie what edge cases are there)
    // yikes - naming convention need to refactor!
    public string actorid { get; set; }
    public string name { get; set; }
    public string sex { get; set; }

Source code for this project is here

Shorter code, much more readable. I like it.

VS Add to Source control

Creates a master branch rather than main so I like to create the repo from GH.

git remote add origin
git branch -M main
git push -u origin main

Nullable reference types

Still need to explicitly turn on nullable reference types.


Nullable reference types - MS Docs]which I’m a fan of.

Perhaps records will help:



With expressions


Positional construction / deconstruction


Target typed new expression


Deploy to *nix

todo - explore whether the apt package repositories have been updated for Ubuntu 18.04 etc.


I’ve updated my main machines to VS 16.8 and .NET 5.0 with no problems as yet. Impressive.